Reputation: 950
I have a collection Project
with documents that look like the following :
{
_id: ObjectId(...),
name: "some name",
members: [
{
user: ObjectId(...),
joined: false,
...
},
{
user: ObjectId(...),
joined: true,
...
},
{
user: ObjectId(...),
joined: true,
...
},
...
]
Given two user
ids, I would like to query all the documents where members
contains at least both users with joined
equal to true
. Additional members could be present, but the two must be present.
I have no clue what to do, especially with $elemMatch
. Any idea ?
Intuitively, I would have done something like this :
Project.find({
members: {
$elemMatch: [
{
user: firstId,
joined: true
},
{
user: secondId,
joined: true
}
]
}
})
Upvotes: 0
Views: 44
Reputation: 937
You can do:
db.collection.find({
"members.joined": true,
"members.user": {
$all: [
3,
4
]
}
})
Upvotes: 1
Reputation: 14520
Use $and over two $elemMatch clauses:
MongoDB Enterprise mongos> db.foo.insert({_id:1,members:[{a:1,joined:true},{a:2,joined:true}]})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise mongos> db.foo.insert({_id:2,members:[{a:1,joined:true},{a:2,joined:false}]})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise mongos> db.foo.find({$and:[{members:{$elemMatch:{a:1,joined:true}}},{members:{$elemMatch:{a:2,joined:true}}}]})
{ "_id" : 1, "members" : [ { "a" : 1, "joined" : true }, { "a" : 2, "joined" : true } ] }
Upvotes: 1
Reputation: 8894
You can achieve this using aggregation.
db.collection.aggregate([{
$addFields:{
members:{
$filter:{
input:"$members",
cond:{
$or:[
{
$and:[
{$eq:["$$this.user",ObjectId("5f49d0623c7e81bfcf37b8ed")]},
{$eq:["$$this.joined",true]}
]
}
,
{
$and:[
{$eq:["$$this.user",ObjectId("5f49d075d14cb1f5e2ff6a77")]},
{$eq:["$$this.joined",true]}
]
}
]
}
}
}
}
}])
Working Mongo playground
Upvotes: 1