Как заменить root полем массива во время конвейера агрегации MongoDB?

#mongodb #aggregation-framework

#mongodb #агрегация-фреймворк

Вопрос:

Допустим, у меня есть users коллекции с roleIds полем, содержащим массив Role ссылок.

 db.users.aggregate([
  {$match:{ _id: ObjectId('5f9453b4484d206714c02a2f') }}, 
  {$project:{ roleIds: 1, _id: 0 }}, 
  {$unwind: "$roleIds"}, 
  {$lookup:{ from: "roles", localField: "roleIds", foreignField: "_id", as: "roles"}}, // <= STEP 4
  {$replaceRoot: "$roles"}
])
  

После ШАГА 4 у меня есть что-то вроде этого:

 { 
  "roles" : [ 
    { "_id" : ObjectId("xxxx"), "name" : "role1" },
    { "_id" : ObjectId("xxxx"), "name" : "role2" },
  ]
}
  

Как я могу преобразовать его в это:

 [ 
  { "_id" : ObjectId("xxxx"), "name" : "role1" },
  { "_id" : ObjectId("xxxx"), "name" : "role2" },
]
  

replaceRoot Похоже, что этап работает, только если поле ролей является документом, а не массивом, в этом случае он выдает ошибку.

Комментарии:

1. можете ли вы предоставить несколько примеров документов?

2. { $unwind: "$roles" } деконструируйте массив раньше $replaceRoot .

Ответ №1:

Это работает:

 db.users.aggregate([
  {$match:{ _id: ObjectId('5f9453b4484d206714c02a2f') }}, 
  {$project:{ roleIds: 1, _id: 0 }}, 
  {$unwind: "$roleIds"}, 
  {$lookup:{ from: "roles", localField: "roleIds", foreignField: "_id", as: "roles"}},
  {$unwind: "$roles"},
  {$replaceRoot: { newRoot: "$roles" }}
])