Reputation: 507
My database schema is somewhat like
{
"_id" : ObjectId("1"),
"createdAt" : ISODate("2017-03-10T00:00:00.000+0000"),
"user_list" : [
{
"id" : "a",
"some_flag" : 1,
},
{
"id" : "b",
"some_flag" : 0,
}
]
}
What I want to do is get the document where id is b & some_flag for the user b is 0.
My query is
db.collection.find({
'createdAt': {
$gte: new Date()
},
'user_list.id': 'b',
'user_list.some_flag': 1
}).sort({
createdAt: 1
})
When I run the query in shell. It returns the doc with id 1(which it shouldn't as the value of some_flag for b is 0)
The thing happening here is,
the query 'user_list.id': user_id matches with the nested object where "id" : b
'user_list.some_flag': 1 is matched with some_flag of nested object where "id": a (as the value of some_flag is 1 here)
What modifications should I make to compare the id & some_flag for the same nested object.
P.S. the amount of data is quite large & using aggregate will be a performance bottleneck
Upvotes: 1
Views: 4239
Reputation: 7920
You should be using $elemMatch
otherwise mongoDB
queries are applied independently on array items, so in your case 'user_list.some_flag': 1
will be matched to array item with id a
and 'user_list.id': 'b'
will match array item with id b
. So essentially if you want to query on array field with and
logic use $elemMatch
as following:
db.collection.find({
'createdAt': {
$gte: new Date()
},
user_list: {$elemMatch: {id: 'b', some_flag: 1}} // will only be true if a unique item of the array fulfill both of the conditions.
}).sort({
createdAt: 1
})
Upvotes: 3
Reputation: 3069
you need to try something like :
db.collection.find({
'createdAt': {
$gte: new Date()
},
user_list: {
$elemMatch: {
id: 'b',
some_flag: 1
}
}
}).sort({
createdAt: 1
});
This will match only user_list entries where _id is b and someflag is 1
Upvotes: 3