Това означава ли, че ако използвате входни променливи в $lookuppipeline, трябва да използвате $expr
Да правилно, по подразбиране във филтри, т.е. във филтърната част на .find()
или в $match
етап на агрегиране не можете да използвате съществуващо поле в документа.
Ако изобщо трябва да използвате стойността на съществуващо поле във вашия филтър за заявки, тогава трябва да използвате конвейер за агрегиране, така че за да използвате конвейер за агрегиране в .find()
или в $match
трябва да обвиете вашата филтърна заявка с $expr. Същият начин за достъп до локални променливи е създаден с помощта на let
на $lookup
филтрирайте в $match
трябва да бъде обвит с $expr
.
Нека разгледаме примера по-долу:
Примерни документи:
[
{
"key": 1,
"value": 2
},
{
"key": 2,
"value": 4
},
{
"key": 5,
"value": 5
}
]
Запитване:
db.collection.find({ key: { $gt: 1 }, value: { $gt: 4 } })
Or
db.collection.aggregate([ { $match: { key: { $gt: 1 }, value: { $gt: 4 } } } ])
Тест: mongoplayground
Ако видите горната заявка и двете въведете 1
&4
се предават в заявката, но проверявате под заявката, където се опитвате да съпоставите key
поле ==value
поле - не работи :
db.collection.aggregate([ { $match: { key: { $eq: "$value" } } } ])
Тест: mongoplayground
По-горе, тъй като сравнявате две съществуващи полета, не можете да направите това, тъй като това означава, че проверявате за документи с key
стойност на полето като низ "$value"
. Така че да се каже, че не е низ, а всъщност е препратка към value
поле трябва да използвате $eq оператор за агрегиране, а не $eq оператор на заявка, както е по-долу:
db.collection.aggregate([ { $match: { $expr: { $eq: [ "$key", "$value" ] } } } ])
Тест: mongoplayground