我在mongodb
中有以下客户订单数据 "_id" : 7,
"customer name" : "John Smith",
"OrderItem" : [
{
"product_category" : "Mobile",
"price" : 900
},
{
"product_category" : "Computer",
"price" : 4200.48
},
{
"product_category" : "TV",
"price" : 670.20
},
{
"product_category" : "TV",
"price" : 960.52
}
]
我需要将每个产品类别平均为:
"_id" : 7,
"customer name" : "John Smith",
"OrderItem" : [
{
"product_category" : "Mobile",
"price" : 900
},
{
"product_category" : "Computer",
"price" : 4200.48
},
{
"product_category" : "TV",
"price" : 815.36
}
]
我试图使用$ unwind但不确定如何对它们进行分组。有什么帮助吗?
答案 0 :(得分:1)
将 aggregation framework 与包含以下各个阶段的管道一起使用:第一个管道阶段中的$match
操作过滤文档流以仅允许匹配的文档(文档与在您的情况下_id = 7
)将未修改的内容传递到下一个管道阶段,即$unwind
操作。这将从输入文档中解构所需的OrderItem
数组字段,以便为每个元素输出一个文档,然后可以对其进行分组,并执行查找类别价格平均值的聚合操作。管道中的下一个阶段是$ group操作,然后按product_category
对输入文档进行分组,并将$avg
表达式应用于price
上的每个组。然后,最后一个阶段$project
重新整形流中的每个文档以产生所需的结果。因此,您的聚合看起来像:
db.collection.aggregate([
{
"$match": {"_id": 7}
},
{
"$unwind": "$OrderItem"
},
{
"$group": {
"_id": "$OrderItem.product_category",
"average_price": {
"$avg": "$OrderItem.price"
}
}
},
{
"$project": {
"_id": 0,
"product_category" : "$_id",
"average_price": 1
}
}
])
<强>结果强>:
{
"result" : [
{
"average_price" : 4200.48,
"product_category" : "Computer"
},
{
"average_price" : 815.36,
"product_category" : "TV"
},
{
"average_price" : 900,
"product_category" : "Mobile"
}
],
"ok" : 1
}
答案 1 :(得分:0)
首先你应该放松OrderItem
然后将它们分组并mongo $avg来计算平均值。下面的聚合将计算avg
db.collectionName.aggregate(
{"$match":{"customer name":"John Smith"}}, // match specified customername
{"$unwind":"$OrderItem"}, // unwind the OrderItem
{"$group":{"_id":"$OrderItem.product_category",
"avg": {"$avg":"$OrderItem.price"} // mongo avg method used for avrage
}}
).pretty()
以上查询返回以下结果
{ "_id" : "Computer", "avg" : 4200.48 }
{ "_id" : "TV", "avg" : 815.36 }
{ "_id" : "Mobile", "avg" : 900 }
但是上面的结果与您给定的预期输出不匹配,因此您应该分组两次以获得准确的输出
db.collectionName.aggregate(
{"$match":{"customer name":"John Smith"}}, //match given criteria
{"$unwind":"$OrderItem"}, //unwind $OrderItem
{"$group":{"_id":"$OrderItem.product_category",
"customerName":{"$first":"$customer name"}, // group all data with calculating avg
"id":{"$first":"$_id"},
"avg":{"$avg":"$OrderItem.price"}}},
{"$group":{"_id":"$id",
"customer Name":{"$first":"$customerName"},
"OrderItem":{"$push": {"product_category":"$_id","price":"$avg"}}}} // group them for expected output
).pretty()
答案 2 :(得分:0)
.aggregate([
{$unwind: "$OrderItem"},
{$group: {
_id: {id: "$_id", cat: "$OrderItem.product_category"},
name: {$first: "$customer name"},
price: {$avg: "$OrderItem.price"}
}},
{$group: {
_id: "$_id.id",
OrderItem: {$push: {product_category: "$_id.cat", price: "$price"}},
"customer name": {$first: "$name"}
}}
])