Suppose I have a insert a set of documents each with an array
field. I would like to find all documents such that their array
field is a subset of
To do this within the context of aggregation, you can use $setIsSubset:
db.collection.aggregate([
// Project the original doc and a new field that indicates if array
// is a subset of ['a', 'b', 'c']
{$project: {
doc: '$$ROOT',
isSubset: {$setIsSubset: ['$array', ['a', 'b', 'c']]}
}},
// Filter on isSubset
{$match: {isSubset: true}},
// Project just the original docs
{$project: {_id: 0, doc: 1}}
])
Note that $setIsSubset
was added in MongoDB 2.6.
In MongoDb, for array field:
"$in:[...]" means "intersection" or "any element in",
"$all:[...]" means "subset" or "contain",
"$elemMatch:{...}" means "any element match"
"$not:{$elemMatch:{$nin:[...]}}" means "superset" or "in"
There is a simple way to do this with aggregation framework or with a find query.
Find query is simple, but you have to use $elemMatch operator:
> db.collection.find({array:{$not:{$elemMatch:{$nin:['a','b','c']}}}}, {_id:0,name:1})
Note that this indicates that we want to not match an array which has an element which is (at the same time) not equal to 'a', 'b' or 'c'. I added a projection which only returns the name field of the resultant document which is optional.