I am trying to aggregate a batch of documents. There are two fields in the documents I would like to $push. However, lets say they are "_id" and "A" fields, I only want $push "_id" and "A" if "A" is $gt 0.
I tried two approaches.
First one.
db.collection.aggregate([{ "$group":{ "field": { "$push": { "$cond":[ {"$gt":["$A", 0]}, {"id": "$_id", "A":"$A"}, null ] } }, "secondField":{"$push":"$B"} }])
But this will push a null value to "field" and I don't want it.
Second one.
db.collection.aggregate([{ "$group": "field": { "$cond":[ {"$gt",["$A", 0]}, {"$push": {"id":"$_id", "A":"$A"}}, null ] }, "secondField":{"$push":"$B"} }])
The second one simply doesn't work...
Is there a way to skip the $push in else case?
ADDED:
Expected documents:
{ "_id":objectid(1), "A":2, "B":"One" }, { "_id":objectid(2), "A":3, "B":"Two" }, { "_id":objectid(3), "B":"Three" }
Expected Output:
{ "field":[ { "A":"2", "_id":objectid(1) }, { "A":"3", "_id":objectid(2) }, ], "secondField":["One", "Two", "Three"] }
In MongoDB, the $push operator is used to appends a specified value to an array. If the mentioned field is absent in the document to update, the $push operator add it as a new field and includes mentioned value as its element. If the updating field is not an array type field the operation failed.
On large collections of millions of documents, MongoDB's aggregation was shown to be much worse than Elasticsearch. Performance worsens with collection size when MongoDB starts using the disk due to limited system RAM. The $lookup stage used without indexes can be very slow.
Without seeing your data and your query it is difficult to answer why aggregate+sort is faster than find+sort. A well indexed(Indexing that suits your query) data will always yield faster results on your find query.
You can use "$$REMOVE"
:
db.collection.aggregate([{ $group:{ field: { $push: { $cond:[ { $gt: ["$A", 0] }, { id: "$_id", A:"$A" }, "$$REMOVE" ] } }, secondField:{ $push: "$B" } } ])
In this way you don't have to filter nulls.
This is my answer to the question after reading the post suggested by @Veeram
db.collection.aggregate([{ "$group":{ "field": { "$push": { "$cond":[ {"$gt":["$A", 0]}, {"id": "$_id", "A":"$A"}, null ] } }, "secondField":{"$push":"$B"} }, { "$project": { "A":{"$setDifference":["$A", [null]]}, "B":"$B" } }])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With