mongodb - 在 mongoDB 聚合框架中组合组和项目

标签 mongodb aggregation-framework

我的文档是这样的:

{ 
  "_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_itemtimestamp。我尝试在查询中使用 $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
  }
}

如果有人能给我提示,如何将分组和其他参数投影到结果集中,我将不胜感激。

最佳 罗布

最佳答案

如果使用 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 运算符应用于非规范化字段(而不是扁平化的 price_information 数组字段)将保证结果中的原始值。因此不需要预排序阶段来定义顺序,因为在这种情况下不需要。

关于mongodb - 在 mongoDB 聚合框架中组合组和项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37549019/

相关文章:

mongodb - 如何在 MongoDB 中查找带计数的连续文档?

mongodb - 复杂聚合命令MongoDB

mongodb - 索引对Mongo按位查询有帮助吗

javascript - 如何发布 meteor 集合中的所有记录......除了一两个

mongodb - Docker mongo image 始终将数据保存在/data/db 目录中

mongodb - 在go mongodb中的From Table上进行比赛阶段

javascript - 在 Mongoose 中对嵌套子文档进行排序和分组

mongodb - 如何在我的 Express.js View 和路由中使用 "cache"mongoDB/Mongoose 结果

node.js - ObjectID 显示 Unicode 乱码而不是字符串

mongodb - 在MongoDB中获取具有最大内部数组大小的文档