#mongodb #aggregation-framework
#mongodb — монгодб #aggregation-framework #mongodb
Вопрос:
Существуют ли другие этапы агрегации или выражения для достижения этого результата? Можно ли использовать выражения массива $map и $ reduce для перебора элементов массива и создания новых пар ключ / значение в корне $$?
Мне любопытно узнать, есть ли лучший способ агрегирования этих данных.
Агрегация:
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)
}
Ответ №1:
Вы можете избежать to $unwind
с помощью $map
a и выполнить непосредственно $replaceRoot
для объекта-результата map :
db.test.aggregate([{
$replaceRoot: {
newRoot: {
$mergeObjects: ["$$ROOT", {
$arrayToObject: {
$map: {
input: "$SubscriptionCharges",
as: "el",
in: {
k: "$$el.ChargeName",
v: "$$el.Quantity"
}
}
}
}]
}
}
}, {
$project: {
SubscriptionCharges: 0
}
}])
Это кажется намного проще 🙂
Комментарии:
1. Теперь это то, о чем я говорю 🙂 Спасибо!