I have the following model:
var PersonSchema = new Schema({ name: String, groups: [ {type: Schema.Types.ObjectId, ref: 'Group'} ], });
I am looking for a query that retrieves all the Persons that are not part of a certain Group (i.e the persons' group array doesn't contain the id of the specified group).
I was thinking about something like this, but I'm not sure it is correct:
Person.find({groups: {$nin: [group._id]})
JavaScript Array includes() The includes() method returns true if an array contains a specified value. The includes() method returns false if the value is not found.
MongoDB provides different types of comparison query operators and $nin (not in) operator is one of them. This operator is used to select those documents where the value of the field is not equal to any of the given value in the array and the field that does not exist.
The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.
Nothing wrong with what you are basically attempting, but perhaps the only clarification here is the common misconception that you need operators like $nin
or $in
when querying an array.
Also you really need to do here is a basic inequality match with $ne
:
Person.find({ "groups": { "$ne": group._id } })
The "array" operators are not for "array targets" but for providing a "list" of conditions to test in a convenient form.
Person.find({ "groups": { "$nin": [oneId, twoId,threeId] } })
So just use normal operators for single conditions, and save $in
and $nin
for where you want to test more than one condition against either a single value or a list. So it's just the other way around.
If you do need to pass a "list" of arguments where "none" of those in the provided list match the contents of the array then you reverse the logic with the $not
operator and the $all
operator:
Person.find({ "groups": { "$not": { "$all": [oneId,twoId,threeId] } } })
So that means that "none of the list" provided are present in the array.
This is a better way to do this in Mongoose v5.11:
Person.find({ occupation: /host/ }).where('groups').nin(['group1', 'group2']);
The code becomes clearer and has more readability.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With