Korzystanie z $where
operatora.
db.collection.find(function() {
return this.docs.length === this.docs.filter(function(doc) {
return typeof(doc.foo) !== "undefined" && doc.foo !== null ;}).length
})
Innym sposobem, aby to zrobić, jest uruchomienie dwóch zapytań:jedno, aby pobrać _id
wszystkich dokumentów, które nie spełniają Twoich kryteriów, przy użyciu distinct()
metoda:
var unwantedIds = db.collection.distinct( "_id", { "docs": { "$elemMatch": { "foo": { "$exists": false } } } } );
Następnie użyj $nin
operatora, aby zwrócić wszystkie dokumenty, które spełniają Twoje kryteria.
db.collection.find({ "_id": { "$nin": unwantedIds } } )
Możesz również użyć .aggregate()
metoda, ale działa to tylko w wersji 3.2 lub nowszej, ponieważ musisz użyć $filter
Pierwszym etapem w potoku jest $match
etap, na którym odfiltrowujesz te dokumenty, w których brakuje pola „foo”. Zmniejsza to całkowitą liczbę dokumentów, które będą przetwarzane w dół potoku. Następny i ostatni etap to $redact
etap. Na tym etapie musisz użyć $size
operator, aby zwrócić rozmiar pola "docs" i rozmiar tablicy dokumentów podrzędnych, w których występuje "foo" i zwrócić wszystkie te dokumenty, w których obie wartości są równe.
db.collection.aggregate([
{ "$match": { "docs.foo": { "$exists": true } } },
{ "$redact": {
"$cond": [
{ "$eq": [
{ "$size": "$docs" },
{ "$size": {
"$filter": {
"input": "$docs",
"as": "doc",
"cond": {
"$ne": [
{ "$ifNull": [ "$$doc.foo", null ] },
null
]
}
}
}}
]},
"$$KEEP",
"$$PRUNE"
]
}}
])