Если у вас есть поддержка MongoDB $replaceRoot
и $arrayToObject
, вы можете использовать это:
db.collection.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$mergeObjects": [
{ "_id": "$_id" },
{ "$arrayToObject": {
"$map": {
"input": "$dept_ids",
"in": { "k": "$$this.dept_name", "v": "$$this.dept_id" }
}
}}
]
}
}}
])
Но вам это даже не нужно, вместо этого просто преобразуйте возвращенные документы:
db.collection.find().map(d =>
Object.assign(
{ _id: d._id },
d.dept_ids.reduce((acc,dep) => Object.assign(acc,{ [dep.dept_name]: dep.dept_id }), {})
)
);
В современных средах ECMASCRIPT, не оболочкой Mongo, а чем-то вроде NodeJS, вы можете немного очистить синтаксис. то есть с драйвером NodeJS:
const mapper = ({ _id, dept_ids }) => ({
_id, ...dept_ids.reduce((acc, { dept_name: k, dept_id: v }) => ({ ...acc, [k]: v }),{})
});
let results = await db.collection('departments').find().map(mapper).toArray();
Оба дают одинаковый результат:
{ "_id" : "xxxxx", "d1" : "dd7867535", "d2" : "dl97087079" }
Так что вам действительно не нужно обрабатывать вещи через конвейер агрегации, что можно сделать довольно просто из полученных данных на клиенте. Вы не «сокращаете» никакие данные, что на самом деле является точкой агрегирования. Таким образом, подобные преобразования действительно «должны» быть сделаны при последующей обработке результатов курсора.