2017-01-24 3 views
2

Я пытаюсь извлечь элемент из массива в 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/#example

MongoDB Версия: 3.4.1
Тестирования среды: Монго Shell

ответ

2

Вы должны использовать оператор $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 ] } 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
])