I have a schema like this
{
members: [{
type: Schema.Types.ObjectId,
ref: 'User'
}]
createdAt: {
type: Date,
default: Date.now
}
...
}
And the docs are
1-
{
members:
["some id 1", "some id 2"]
},
createdAt: "someTime ago"
2-
{
members:
["some id 1", "some id 2", "some id 3"]
},
createdAt: "someTime ago"
I want to find the docs which match the exact an array of elements
['some id 1', 'some id 2']
ie doc 1 in the above sample docs
How this could be possible?
Any help would be appreciated.
To query if the array field contains at least one element with the specified value, use the filter { <field>: <value> } where <value> is the element value. To specify conditions on the elements in the array field, use query operators in the query filter document: { <array field>: { <operator1>: <value1>, ... } }
Return valueThe returned value could be an array of documents, a single document if it matches only one, or an empty array if no document is matched.
To search the array of object in MongoDB, you can use $elemMatch operator. This operator allows us to search for more than one component from an array object.
As long as you do realize that you are matching on the ObjectId and not actually anything in the referenced collection you can use the $in
operator:
db.collection.find({ "members": { "$in": [ "some id 1", "some id 2" ] } })
Where of course those are your actual ObjectId values.
But if you really mean a document that has exactly that array, then you just pass in the array:
db.collection.find({ "members": [ "some id 1", "some id 2" ] })
And if it must have both the elements but could have others then currently you need to use an $and
expression:
db.collection.find({ "$and": [
{ "members": "some id 1" },
{ "members": "some id 2" }
]})
But from release 2.6 an on-wards you can properly use the $all
operator to effectively do the same:
db.collection.find({ "members": { "$all": [ "some id 1", "some id 2" ] } })
The other form is matching those two elements only, but in any order. So there are two approaches:
db.collection.find({ "$or": [
{ "members": [ "some id 1", "some id 2" ] },
{ "members": [ "some id 2", "some id 1" ] }
]})
This uses a logical $or
to say that the array must be exact but can be arranged either way. And the other approach:
db.collection.find({ "$and": [
{ "members": "some id 1" },
{ "members": "some id 2" }
{ "members": { "$size": 2 } }
]})
So this would use $size
in order to make sure that when the array contained both of the elements that matched that is also only had just two elements. Which is a nicer syntax than using $or
, especially for larger arrays.
And in the future releases as mentioned this gets even cleaner:
db.collection.find({ "$and": [
{ "members": { "$all": [ "some id 1", "some id 2" ] } },
{ "members": { "$size": 2 } }
]})
That fairly much covers every interpretation
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