Add some data in aggregation with $match in MongoDb - json

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

Related

Sequelize top level where with Op.or gives error

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!

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

Mongoose select an object in Array with specific property

From this 'houses' collection
{
_id: "0",
rooms: [
{
roomName: "living-room"
chairs: "6"
},
{
roomName: "kitchen"
chairs: "0"
}
]
}
I need to find the house with _id = 0, and select only
the 'chairs' from the "living-room" so that the result looks like this:
{
chairs: 6
}
I think of something that looks like this:
House.findOne({_id: '0'}).select('rooms.chairs') // but only from {roomName: "living-room"}
How do I complete the query?
How about this one:
db.houses.aggregate([
{ $match: { _id: "0" } },
{
$project: {
chairs: {
$filter: {
input: "$rooms",
cond: { $eq: ["$$this.roomName", "living-room"] }
}
}
}
},
{
$replaceRoot: {
newRoot: {
chairs: { $arrayElemAt: ["$chairs.chairs", 0] }
}
}
},
])
db.house.findOne({"rooms.chairs":"6"},{"rooms.$":1})

MongoDb: Retrieve all documents higher than the average value of a column

I have created a collection using this piece of code.
db.createCollection("item", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["_id", "item_name", "unit_price"],
properties: {
_id: {
bsonType: "string",
description: "must be a string and is required",
minLength: 3,
maxLength: 5,
pattern: "I[0-9]*$"
},
item_name: {
bsonType: "string",
description: "must be a string and is required"
},
unit_price: {
bsonType: "double"
}
}
}
},
validationLevel: "moderate"
})
and I have inserted records in the Item collection. Now I wish to list the items whose "unit_price" is less than the average price of all items.
What I have tried is
db.item.aggregate([{
$group: {
_id: null,
averageUnitPrice: {
$avg: "$unit_price"
}
}
}])
I have tried to use the above piece of code but I am not able to figure out how to take this average and use it to retrieve the documents higher than averageUnitPrice. Any help is highly appreciated!! Thanks a tonn!!!.
So I finally figured it out. This query will give me the average and the list of items which are less than the average value.
db.item.aggregate([{
$group: {
_id: null,
avg_price: {
$avg: "$unit_price"
},
unit_price: {
"$addToSet": "$unit_price"
}
},
},{
$project: {
avg_price: "$avg_price",
unit_price: {
$filter: {
input: "$unit_price",
as: "unit_prices",
cond: {
$lt: ["$$unit_prices", "$avg_price"]
}
}
}
}
}
])

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 } },
]
}
]},
});