Sequelize top level where with Op.or gives error - mysql

I am upleveling the includes to top level "where" so that I can OR it:
MODEL_A.findAll({
where: {
[Op.Or] : [
{
'$MODEL2_DETAIL.COLNAME$' : { [Op.eq]: 5 }
}, {
'$MODEL3_DETAIL.COLNAME$' : { [Op.eq]: 5 }
}
]
},
include: [{
model: MODEL2
as: 'MODEL2_DETAIL'
}, {
model: MODEL3,
as: 'MODEL3_DETAIL'
}
]
})
It gives error:
"Invalid value { '$MODEL2_DETAIL.COLNAME$': { [Symbol(eq)]: 5 } }"
If I put it without the Op.Or, it works
MODEL_A.findAll({
where: {
'$MODEL2_DETAIL.COLNAME$' : { [Op.eq]: 5 }
}
}...
Above works!
Any other suggestions how I can OR on multiple models?
https://sequelize.org/master/manual/eager-loading.html

Needs to be Op.or instead of Op.Or
Thank you #anatoly for noticing!

Related

How to output object of an array in the root of the document in MongoDB using aggregation?

I have this document :
{"_id":"1", "elem":"ok",
"arrayOfObjects":[
{"type":"k","fieldx":"lol"},
{"type":"SndObject","fieldy":"foo"},
{"type":"Object1","fieldx":"bob"}
]
}
what is the aggregation to have this output:
{"_id":"1", "elem":"ok",
"Object1":[
{"type":"Object1","fieldx":"lol"},
{"type":"Object1","fieldx":"bob"}
],
"SndObject":[{"type":"SndObject","fieldy":"foo"}]
}
I found a way out, but it need me to know all the type i have:
{
"$addFields" : {
"Object1" : {
"$filter": {
"input": "$arrayOfObjects",
"as": "types",
"cond": {
"$and": [{ "$eq": [ "$$types.type", "Object1" ] }]
}
}
}
}
}
It would be best if i can loop over my arrayOfObjects and get the same result without pre knowledge of the type.
Might be there would be more easy option than this,
$unwind deconstruct arrayOfObjects array
$group by _id, type and elem, construct array of arrayOfObjects
$arrayToObject convert k and v from array to object
$group by _id and merge objects in root
db.collection.aggregate([
{ $unwind: "$arrayOfObjects" },
{
$group: {
_id: {
type: "$arrayOfObjects.type",
_id: "$_id"
},
elem: { $first: "$elem" },
arrayOfObjects: { $push: "$arrayOfObjects" }
}
},
{
$group: {
_id: "$_id._id",
elem: { $first: "$elem" },
arrayOfObjects: {
$mergeObjects: {
$arrayToObject: [[
{
k: "$_id.type",
v: "$arrayOfObjects"
}
]]
}
}
}
}
])
Playground

how to search by included model

let find_Query = {
attributes: ["id"],
include: [
{
model: Tender_details,
include: [{
model: Categories,attributes: ["id","category_name"],
where:{}
},
{
model: SubCategories,attributes: ["id","sub_category_name"],
where:{}
}
],
where: {}
},
],
where: {} };
switch (key) {
case "search":
find_Query.include[0].where[Op.or] = [
{
"$Categories.category_name$": {
[Op.like]: `%${req.query.search}%`
}
},
{
"$Subcategories.sub_category_name$": {
[Op.like]: `%${req.query.search}%`
}
}
];
break;
default:
break;
I have used this code. In this code, i'm using [Op.or]. but it's not working properly.
In this code, i want to find data by category_name and sub_category_name from included model

Loopback filter NOT BETWEEN date

I'm using loopback models to filter a list of events with start and end dates and I want to return a list of events that are NOT between two specific dates. I thought something like this should work:
const eventList = await Events.find({
where: {
startDate: {
not: {
between: [unavailableStarting, unavailableEnding],
},
},
endDate: {
not: {
between: [unavailableStarting, unavailableEnding],
},
},
},
});
If you take out the not part, this works fine for getting all events that ARE between the dates. How do I make a NOT BETWEEN filter work?
As far as I can tell there is no way to use NOT BETWEEN with loopback models, but I did make it work with lt gt:
const eventList = await Events.find({
where: {
and:[{
or: [
{ startDate: { lt: unavailableStarting } },
{ startDate: { gt: unavailableEnding } },
]
},
{
or: [
{ endDate: { gt: unavailableStarting } },
{ endDate: { lt: unavailableEnding } },
]
}
]},
});

Add some data in aggregation with $match in MongoDb

I am using mongoDb, restheart and also new in these technologies. I want to add one more field in aggregation. So my exist aggregation working fine. I am sharing aggregation
Aggregation:
aggrs: [{
type: "pipeline",
uri: "by_time",
stages: [{
_$match: {
bus::destination: {
_$in: {
_$var: "stands"
}
},
bus::eta: {
_$gte: {
_$var: "dateFrom"
},
_$lte: {
_$var: "dateTo"
}
}
}
},
]
}]
Json Data:
{
_id: "1938378_32323",
bus: {
valid: true,
eta: {
$date: 1500661200000
},
busDate: {
$date: 1500595200000
},
etd: {
$date: 1500661200000
},
origin: "kalu",
destination: "cell",
},
apose: false
}
Above aggregation working fine, But I want to add "apose" in aggregation. So I have implemented this code for aggregation.
stages: [{
_$match: {
bus::destination: {
_$in: {
_$var: "stands"
}
},
bus::eta: {
_$gte: {
_$var: "dateFrom"
},
_$lte: {
_$var: "dateTo"
}
},
"apose": {
"_$eq": {
"_$var": "opposit"
}
}
}
},
]
But When I hit this aggregation, I got only
{"_embedded":[],"_size":0,"_total_pages":0,"_returned":0}
My hitting url is
http:...abc.../_aggrs/by_time?avars={"stands":["KALU","MAL","SALU"],"dateFrom":{"$date":"2007-12-21T01:30:00Z"},"dateTo":{"$date":"2010-02-15T09:30:00Z"},"opposit":"false"}
your answer is valuable for me. Thanks

how to use aggregate for group and count in mongoose?

I have json object in my db like as follows:
{
'name':'test1',
'game':'cric'
},
{
'name':'test1',
'game':'cric'
},
{
'name':'test1',
'game':'football'
},
{
'name':'test2'
'game':'football'
}
I am trying to get output as follows
{
'name':'test1'
'game':[{cric: 2}, {football:1}],
'totalCount': 3
}
I used aggregate query for that.
group {'_id':{name:'$name'}, {game:{$addToSet:$game}}
project {name : $name, game: $game}
I got output as
{name: 'test1', 'game':[cric, football]}
Now i have question that, how can i get count of game. it current example for cricket it is 2 and for football 1 for test1 user
A similar question is answered here.
For your particular case it would be:
db.collection.aggregate([
{
$group: {
_id: { name: "$name", game: "$game" },
games: { "$push": "$game" },
total: { "$sum": 1 }
}
},
{
$group: {
_id: { name: "$_id.name" },
games: { $addToSet: { game: "$_id.game", sum:"$total" } }
}
}
])
And the result should look like:
{
"result" : [
{
"_id" : {
"name" : "test1"
},
"games" : [
{
"game" : "cric",
"sum" : 2
},
{
"game" : "football",
"sum" : 1
}
]
},
{
"_id" : {
"name" : "test2"
},
"games" : [
{
"game" : "football",
"sum" : 1
}
]
}
],
"ok" : 1
}
Here is my solution to test1 name record
db.getCollection('COLLECTION_NAME').aggregate([
{$match : {name : "test1"}},
{
$group: {
_id: "$game" ,
total: { "$sum": 1 },
name : {$first : "$name"}
}
},
{
$group: {
_id : "$name",
games: { $addToSet: { game: "$_id", sum:"$total" } },
totalCount : {$sum : "$total"}
}
}
])