Jak podano, $where
jest dobrym rozwiązaniem, gdy nie trzeba kontynuować logiki w potoku agregacji.
Ale jeśli to zrobisz, użyj $redact
, aby $map
przekształcić "wartość" w tablicę i użyć porównania $setIsSubSet
. Jest to najszybszy sposób, aby to zrobić, ponieważ nie trzeba powielać dokumentów za pomocą $unwind
:
db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": { "$setIsSubset": [
{ "$map": {
"input": { "$literal": ["A"] },
"as": "a",
"in": "$value"
}},
"$array"
]},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
$redact
operator rurociągu pozwala PRZETWARZANIE warunku logicznego ciągu $cond
i używa specjalnych zabiegów $$KEEP
do „keep "dokument, w którym warunek logiczny jest prawdziwy lub $$PRUNE
, aby" usunąć "dokument, w którym warunek był fałszywy.
Pozwala to na pracę jak $project
z kolejnym $match
, ale w jednym etapie rurociągu, który jest bardziej wydajny.
Biorąc pod uwagę, że są to natywnie kodowane operatory, a nie JavaScript, jest to prawdopodobnie "najszybszy" sposób na dopasowanie. Tak więc pod warunkiem, że używasz wersji MongoDB 2.6 lub wyższej, to jest sposób, w jaki powinieneś robić to, aby porównać te elementy w dokumencie.
nie próbowałem tego, ale myślę, że prawdopodobnie chcesz '$ elemMatch' (patrz [DOCS] (http://docs.mongodb.org/manual/reference/operator/query/elemMatch/# op._S_elemMatch)) zamiast '$ in' - chcesz przetestować, czy wartość jest tablicą, a nie czy tablica ma wartość! – DNA
Naprawdę powinieneś wrócić i spojrzeć na to pytanie, ponieważ każdy, kto zasugerował '$ unwind', dostarczył ci najgorszą możliwą odpowiedź, którą możesz zastosować w swoim kodzie. Złożono znacznie lepsze alternatywy. –