Фильтровать массив в поле массива вложенных документов
Я пытаюсь получить элемент из массива в MongoDB. Я думаю, что фильтр агрегации является правильным для применения. Но я уже пытался миллион раз, я до сих пор не могу найти, в чем проблема. Не могли бы вы дать мне руку?
Пример данных MongoDB:
{
"_id" : 12,
"items" : [
{
"columns" : [
{
"title" : "hhh",
"value" : 10
},
{
"title" : "hahaha",
"value" : 20
}
]
},
{
"columns" : [
{
"title" : "hiii",
"value" : 50
}
]
}
]
}
Мое решение:
db.myCollection.aggregate([
{
$project: {
items: {
$filter: {
input: "$items",
as: "item",
cond: { $eq: [ "$$item.columns.title", "hahaha" ]}
}
}
}
}
]).pretty()
Мой результат:
{
"_id" : 15,
"items" : [
{
"columns" : [ ]
},
{
"columns" : [ ]
}
]
}
Ожидаемый результат:
{
"_id" : 15,
"items" : [
{
"columns" : [
{
"title" : "hahaha",
"value" : 20
}
]
},
{
"columns" : []
}
]
}
Я проверил ссылку в Монго: https://docs.mongodb.com/manual/reference/operator/aggregation/filter/
Версия MongoDB:3.4.1
Среда тестирования: Mongo Shell
1 ответ
Вам нужно использовать $map
оператор массива для $filter
вложенный массив в вашем поддокументе. Также вы должны сделать это в $addFields
Этап конвейера агрегации для автоматического включения всех остальных полей в результат запроса, если они вам нужны.
Вы также можете заменить $addFields
этап с $project
как вы делали, но в этом случае вам нужно будет явно включить все остальные поля.
let value = "hahaha";
db.coll.aggregate([
{
"$addFields": {
"items": {
"$map": {
"input": "$items",
"as": "item",
"in": {
"columns": {
"$filter": {
"input": "$$item.columns",
"as": "elt",
"cond": { "$eq": [ "$$elt.title", value ] }
}
}
}
}
}
}
}
])