Существуют ли другие этапы агрегации или выражения для достижения этого результата? Можно ли использовать $ map и выражение $ array array для перебора элементов массива и создания новых пар ключ / значение в $$ ROOT?
Мне любопытно узнать, есть ли лучший способ агрегирования этих данных.
Aggregation:
db.getCollection("test").aggregate([
{ $unwind: "$SubscriptionCharges"},
{ $addFields: { sc: { $objectToArray: "$SubscriptionCharges"} }},
{ $addFields: { cc: { $arrayElemAt: [ { $filter: { input: "$sc", as: "ch", cond: { $eq: [ "$$ch.k", "ChargeName"]} }}, 0 ]},
q: { $arrayElemAt: [ { $filter: { input: "$sc", as: "ch", cond: { $eq: [ "$$ch.k", "Quantity"]} }}, 0 ]},
} },
{ $addFields: { "cc.k": "$cc.v", "cc.v": "$q.v" }},
{ $addFields: { charges: { $arrayToObject: [[ "$cc" ]] } }},
{ $project: { SubscriptionCharges: 0, sc: 0, cc: 0, q: 0}},
{ $group: { _id: "$_id", CustomerNumber: { $first: "$CustomerNumber"}, CustomerType: { $first: "$CustomerType"}, CustomerName: { $first: "$CustomerName"}, charges: { $mergeObjects: "$charges"} }},
{ $replaceRoot: { newRoot: { $mergeObjects: [ "$$ROOT", "$charges" ]}}},
{ $project: { charges: 0}}
])
Фактический:
{
"_id" : BinData(3, "vRoG6+EVGEOOu6WYALc3VA=="),
"CustomerNumber" : "ABC",
"CustomerType" : "Direct",
"CustomerName" : "Test",
"SubscriptionCharges" : [
{
"ChargeCode" : "Code-1",
"Price": 12,
"ChargeName" : "Name-1",
"Quantity" : NumberLong(25),
},
{
"ChargeCode" : "Code-2",
"Price": 15,
"ChargeName" : "Name-2",
"Quantity" : NumberLong(1),
},
],
}
Ожидаемое:
{
"_id" : BinData(3, "vRoG6+EVGEOOu6WYALc3VA=="),
"CustomerNumber" : "ABC",
"CustomerType" : "Direct",
"CustomerName" : "Test",
"Name-1": NumberLong(25),
"Name-2":NumberLong(1)
}