Reputation: 85
I have this aggregate query, which takes really long to get results and I only need the Aggregation framework because of the $unwind parameter. To be specific I have to query things that are in an array. How can I rewrite this aggregation query into a find query and do you think performance would be better with find?
db.cms.aggregate([{"$unwind":"$values"},
{"$match": {"values.timestamp":{"$exists":1}}},
{"$match": {"values.sensor":"V1"}},
{"$match": {"values.timestamp":{"$gte":"2018-02-07 14:00:16.163","$lte":"2018-02-07 14:00:16.163"}}}] )
The documents in the collection look like this
_id" : ObjectId("5a8ac17569191602538b65d2"),
"values" : [
{
"sensor" : "B",
"unit" : "mm/s2",
"timestamp": "2018-02-07 14:00:16.163"
},
{
"sensor" : "Bp",
"unit" : "mm/s2",
"timestamp": "2018-02-07 14:00:16.163"
},
{
"sensor" : "Bt",
"unit" : "mm/s2",
"timestamp": "2018-02-07 14:00:16.163"
},
{
"sensor" : "V1",
"timestamp" : "2018-02-07 14:00:16.163",
"unit" : "V"
}]}
Upvotes: 2
Views: 9027
Reputation: 4305
If all you need is filtering out, simply use the $filter
operator:
db.cms.aggregate([
{
$project: {
values : {
$filter: {
input: "$values",
as: "value",
cond: {
$and: [
{ $ifNull: [ "$$value.type", false ] },
{ $eq: [ "$$value.sensor", "V1" ] },
{ $eq: [ "$$value.timestamp", "2018-02-07 14:00:16.163" ] },
]
}
}
}
}
}
])
By the way, the cond
field of the aggregational $filter
operator requires an expression that resolves to a boolean value. We cannot use
the $exists
nor any query operator, and its aggregational equivalent is the $ifNull
operator.
Upvotes: 4