Как вернуть только ОДИН соответствующий вложенный документ (не массив) из массива вложенных документов в MongoDB?

В моей коллекции:

{ "code": xx1
  "valueList": [
                  { "id": "yy1", "name": "name1"},
                  { "id": "yy2", "name": "name2"},
                  { "id": "yy3", "name": "name3"}              
               ]
},
{ "code": xx2
  "valueList": [
                  { "id": "yy4", "name": "name4"},
                  { "id": "yy5", "name": "name5"},
                  { "id": "yy6", "name": "name6"}              
               ]
}

Я хочу вернуть конкретный ОДИН соответствующий поддокумент (а не массив), как показано ниже:

{ "id": "yy3", "name": "name3"}  

Я пробую ниже код:

findOne({ "code": "xx1",
          "valueList.name": "yy3"
       })
.select({ "valueList.$": 1});

Вместо этого он возвращает массив:

 {
   "valueList": [{ "id": "yy3", "name": "name3" }]
 }

Как я могу это решить? Спасибо


person elvin    schedule 15.02.2019    source источник


Ответы (1)


Вы можете использовать следующую агрегацию:

db.col.aggregate([
    { $match: { "valueList.id": "yy3" } },
    { $unwind: "$valueList" },
    { $match: { "valueList.id": "yy3" } },
    { $replaceRoot: { newRoot: "$valueList" } }
])

Сначала $match отфильтрует все ненужные документы, затем вы можете использовать $unwind, чтобы получить valueList элемент за документ, а затем снова $match, чтобы получить только тот, у которого yy3 на последнем этапе, вы можете использовать $replaceRoot для продвижения valueList элемента на верхний уровень.

person mickl    schedule 15.02.2019
comment
Он работает, но возвращает массив: [{id: yy3, name: name3}]. Возможно ли, что он может просто вернуть сам вложенный документ без массива: {id: yy3, name: name3} (примечание: без [])? Тогда будет идеально, спасибо - person elvin; 15.02.2019
comment
@elvin, это необходимо обрабатывать в логике вашего приложения, агрегат и поиск всегда будут возвращать массив, даже если это одноэлементный массив. - person mickl; 15.02.2019