我的文档如下:
{
"_id" : ObjectId("5748d1e2498ea908d588b65e"),
"some_item" : {
"_id" : ObjectId("5693afb1b49eb7d5ed97de14"),
"item_property_1" : 1.0,
"item_property_2" : 2.0,
},
"timestamp" : "2016-05-28",
"price_information" : {
"arbitrary_value" : 111,
"hourly_rates" : [
{
"price" : 74.45,
"hour" : "0"
},
{
"price" : 74.45,
"hour" : "1"
},
{
"price" : 74.45,
"hour" : "2"
},
]
}
}
我通过以下方式平均每天的价格:
db.hourly.aggregate([
{$match: {timestamp : "2016-05-28"}},
{$unwind: "$price_information.hourly_rates"},
{$group: { _id: "$unique_item_identifier", total_price: { $avg: "$price_information.hourly_rates.price"}}}
]);
我正在努力在结果集中引入(投射)其他参数。我希望在结果集中也有some_item
和timestamp
。我尝试在查询中使用$project: {some_item: 1, total_price: 1, ...}
,但这不对。
我想要的输出就像:
{
"_id" : ObjectId("5693afb1b49eb7d5ed97de27"),
"someItem" : {
"_id" : ObjectId("5693afb1b49eb7d5ed97de14"),
"item_property_1" : 1.0,
"item_property_2" : 2.0,
},
"timestamp" : "2016-05-28",
"price_information" : {
"avg_price": 34
}
}
如果有人可以给我一个提示,如何将分组和其他参数投射到结果集中,我会很感激。
最佳罗布
答案 0 :(得分:6)
如果使用MongoDB 3.2及更高版本,您可以在 $avg
管道中使用 $project
,因为它会返回指定表达式的平均值或每个文件的表达列表,例如
db.hourly.aggregate([
{ "$match": { "timestamp": "2016-05-28" } },
{
"$project": {
"price_information": {
"avg_price": { "$avg": "$price_information.hourly_rates.price" }
},
"someItem": 1,
"timestamp": 1,
}
}
]);
在早期版本的MongoDB中, $avg
仅在 $group
阶段提供。要包含其他字段,请在分组中使用 $first
运算符:
db.hourly.aggregate([
{ "$match": { "timestamp": "2016-05-28" } },
{ "$unwind": "$price_information.hourly_rates" },
{
"$group": {
"_id": "$_id",
"avg_price": { "$avg": "$price_information.hourly_rates.price" },
"someItem": { "$first": "$some_item" },
"timestamp": { "$first": "$timestamp" },
}
},
{
"$project": {
"price_information": { "avg_price": "$avg_price" },
"someItem": 1
"timestamp": 1
}
}
]);
注意: $first
阶段中 $group
运算符的使用在很大程度上取决于文档的方式进入该管道以及按组排序。由于 $first
将返回按键共享相同组的一组文档中的第一个文档值,因此 $group
阶段逻辑上应位于 $sort
阶段,以定义的顺序输入文档。只有在知道正在处理数据的顺序时才使用它。
但是,由于上面是主文档的_id
键分组, $first
运算符应用于非非规范化字段(而不是展平{{1} }} array fields)将保证结果中的原始值。因此,不需要预先排序阶段来定义订单,因为在这种情况下不需要。