Можно ли использовать $project для возврата поля в качестве документа верхнего уровня в запросе агрегирования mongo?

У меня есть документ, похожий на следующий, где я хочу вернуть поле текущих документов верхнего уровня в качестве самого документа верхнего уровня в массиве результатов:

{ 
  field1:{contents:{}}
  field2:{othercontent:{}}
}

Я хочу, чтобы результаты моего запроса на агрегацию возвращали следующие

{
  contents:{}
}

Можно ли это сделать с помощью $project и структуры агрегации?

Ответ 1

Да, вы можете использовать $project для этого. Вы просто должны сказать ему, чтобы получить вложенный объект contents, используя dot notation:

db.items.aggregate( {$project: {contents:'$field1.contents'}} );

Кроме того, если вы хотите скрыть поле _id от вывода, вы можете указать _id: 0 в параметрах $project:

db.items.aggregate( {$project: {contents:'$field1.contents', _id:0}} );

Ответ 2

  • Начиная с Mongo 3.4, оператор агрегации $replaceRoot может использоваться для замены документа другим (в нашем случае вложенным документом):

    // { field1: { content: { a: 1, b: 2 } }, field2: { othercontent: {} } }
    // { field1: { content: { c: 1, d: 2 } }, field2: { othercontent: {} } }
    db.collection.aggregate({ $replaceRoot: { newRoot: "$field1" } })
    // { content: { a: 1, b: 2 } }
    // { content: { c: 1, d: 2 } }
    
  • Начиная с Mongo 4.2, оператор $replaceWith также может быть использован:

    db.collection.aggregate({ $replaceWith: "$field1" })