Czy to oznacza, że jeśli używasz zmiennych wejściowych w $lookuppipeline, musisz użyć $expr
Tak poprawnie, domyślnie w filtrach tj.; w części filtrującej .find() lub w $match etap agregacji, nie możesz użyć istniejącego pola w dokumencie.
Jeśli w ogóle, jeśli chcesz użyć istniejącej wartości pola w filtrze zapytania, musisz użyć potoku agregacji, więc aby użyć potoku agregacji w .find() lub w $match musisz otoczyć zapytanie filtrujące $expr. Ten sam sposób dostępu do zmiennych lokalnych został utworzony za pomocą let z $lookup filtruj w $match musi być opakowany przez $expr .
Rozważmy poniższy przykład:
Przykładowe dokumenty:
[
{
"key": 1,
"value": 2
},
{
"key": 2,
"value": 4
},
{
"key": 5,
"value": 5
}
]
Zapytanie:
db.collection.find({ key: { $gt: 1 }, value: { $gt: 4 } })
Or
db.collection.aggregate([ { $match: { key: { $gt: 1 }, value: { $gt: 4 } } } ])
Test: plac zabaw dla mongo
Jeśli zobaczysz powyższe zapytanie, wprowadź jednocześnie 1 &4 są przekazywane do zapytania, ale sprawdzasz poniżej zapytanie, w którym próbujesz dopasować key pole ==value pole - nie działa :
db.collection.aggregate([ { $match: { key: { $eq: "$value" } } } ])
Test: plac zabaw dla mongo
Powyżej, gdy porównujesz dwa istniejące pola, nie możesz tego zrobić, ponieważ oznacza to, że sprawdzasz dokumenty za pomocą key wartość pola jako ciąg "$value" . Powiedzieć, że nie jest to ciąg znaków, to w rzeczywistości odwołanie do value w polu musisz użyć operatora agregacji $eq zamiast operatora zapytania $eq, jak poniżej:
db.collection.aggregate([ { $match: { $expr: { $eq: [ "$key", "$value" ] } } } ])
Test: plac zabaw dla mongo