I have Game collection in my DB:
var game = {
players: [{username:\"user1\", status:\"played\"},
{username:\"user2\", status:\"accepted\"}]
}
<
If you only have one other status than "played" use the query:
db.games.find({ "players.status": { $ne:"accepted" } })
You can adjust the query to handle more status values, as long as they are all known at the time of the query.
Use the $unwind feature of the aggregation framework:
db.collection.aggregate([{$unwind:"$players.status"},{$match:{"players.status":"played"},{$project:{"_id":0,"players.status":1}}])
(check out this answer: https://stackoverflow.com/a/15082321/1214167)
I ran into this problem too. I was trying to use $all
and making little to no progress. It helped to flip my perspective on the problem and use $not
instead. I wrote about what I found here.
In your situation, you should be able to do something like this:
db.games.find({
players: {
$not: {
$elemMatch: {
status: { $ne: "played" }
}
}
}
})
Find all documents with a player status not equal to "played"
and return the inverse of that set. The nice thing about this is that you never have to worry about adding more status values.