是否有其他聚合阶段或表达式来实现此结果?是否可以使用$map和$reduce数组表达式来迭代数组项并在$$ROOT中创建新的键/值对?
我很想知道是否有更好的方法来聚合这些数据。
聚合:
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)
}发布于 2019-03-22 05:58:57
您可以避免使用$map执行$unwind,而是直接对地图的对象结果执行$replaceRoot:
db.test.aggregate([{
$replaceRoot: {
newRoot: {
$mergeObjects: ["$$ROOT", {
$arrayToObject: {
$map: {
input: "$SubscriptionCharges",
as: "el",
in: {
k: "$$el.ChargeName",
v: "$$el.Quantity"
}
}
}
}]
}
}
}, {
$project: {
SubscriptionCharges: 0
}
}])它看起来简单得多:)
https://stackoverflow.com/questions/55289059
复制相似问题