我有以下MongoDB数据模型:
{
"_id" : ObjectId("53725814740fd6d2ee0ca2bb"),
"date" : "2014-01-01",
"establishmentId" : 1,
"products" : [
{
"productId" : 1,
"price" : 7.03,
"someOtherInfo" : 325,
"somethingElse" : 6878
},
{
"productId" : 2,
"price" : 4.6,
"someOtherInfo" : 243,
"somethingElse" : 1757
},
{
"productId" : 3,
"price" : 2.14,
"someOtherInfo" : 610,
"somethingElse" : 5435
},
{
"productId" : 4,
"price" : 1.45,
"someOtherInfo" : 627,
"somethingElse" : 5762
},
{
"productId" : 5,
"price" : 3.9,
"someOtherInfo" : 989,
"somethingElse" : 3752
}
}
获得所有机构平均价格的最快方法是什么?是否有更好的数据模型来实现这一目标?
答案 0 :(得分:0)
aggregation操作应该很好地处理这个问题。我建议调查$unwind操作。
这些方面的某些内容应该有用(仅作为示例):
db.collection.aggregate(
{$match: {<query parameters>}},
{$unwind: "$products"},
{
$group: {
_id: "<blank or field(s) to group by before averaging>",
$avg: "$price"
}
}
);
以此样式构建的聚合应生成具有所需数据的JSON对象。
答案 1 :(得分:0)
由于其他任何提供的语法错误,更直接的答案是:
db.collection.aggregate([
{ "$unwind": "$products" },
{ "$group": {
"_id": null,
"avgprice": { "$avg": "$products.price" }
}}
])
此处aggregation framework的用法是首先$unwind
数组,这是一种将数组中的内容“反规范化”为单独文档的方法。
然后在$group
阶段,您将值null
传递给_id
,这意味着“将所有内容分组”并传递您的$products.price
(请注意点符号)进入$avg
运算符,以返回集合中所有文档中所有子文档条目的总平均值。
有关详细信息,请参阅full operator reference。
答案 2 :(得分:0)
我找到的最佳解决方案是:
db.collection.aggregate([
{$match:{date:{$gte:"2014-01-01",$lte:"2014-01-31"},establishmentId:{$in:[1,2,3,4,5,6]}}
{ "$unwind": "$products" },
{ "$group": {
"_id": {date:"$date",product:"$products.productId"},
"avgprice": { "$avg": "$products.price" }
}}
])
我发现的一点是,首先使用匹配然后放松更好,所以放松的项目更少。这导致整个过程更快。