如何在不改变聚合组的keyf函数的情况下指定原有的参数



这是我开始的简化集合:

[{
  "_id" : ObjectId("577a598ecab5bb4a002c19da"),
  "user" : ObjectId("5775549f9fcaae26c9149026"),
  "expense" : 12.87,
  "created" : ISODate("2016-07-04T12:43:07.181Z")
},
{
  "_id" : ObjectId("577a598ecab5bb4a002c19db"),
  "user" : ObjectId("5775549f9fcaae26c9149026"),
  "expense" : 12.87,
  "created" : ISODate("2016-07-06T12:10:07.181Z")
},
{
  "_id" : ObjectId("977a598ecai6bb4a002c19du"),
  "user" : ObjectId("6775539f9fciae26c9149027"),
  "expense" : 12.87,
  "created" : ISODate("2016-07-07T10:43:07.181Z")
},
....
]

我想要group,并计算created参数特定日期的所有users

我正在尝试这个,但它不工作:

db.getCollection('expenses').group({
            keyf: function(doc) {
               return { 
                   "day_created": doc.created.getDate(),
                   "user" : doc.user // or  "user" : 1
                }
            },
            cond: {},
            reduce: function (value, result) {
                result.total++;  
            },
            initial: {
                total: 0
            }
 });

相反,单个组可以完美地工作(对于日期):

db.getCollection('expenses').group({
            keyf: function(doc) {
               return { 
                   "day_created": doc.created.getDate()
                }
            },
            cond: {},
            reduce: function (value, result) {
                result.total++;  
            },
            initial: {
                total: 0
            }
 });
<<p> 反应/strong>:
[
    {
        "day_created" : 17,
        "total" : 5385
    },
    {
        "day_created" : 18,
        "total" : 6338
    },
 ....
]

相反,单独的组可以完美地工作(对于用户):

db.getCollection('tickets').group({
            key : {user : 1},
            cond: {},
            reduce: function (value, result) {
                result.total++;  
            },
            initial: {
                total: 0
            }
 });
<<p> 反应/strong>:
[
    {
        "user" : ObjectId("5776f0143543e84a003d53bf"),
        "total" : 155
    },
    {
        "user" : ObjectId("577554a89fcaae26c914a8bd"),
        "total" : 494
    },
...
]

我使用MongoDB shell版本:3.2.1。如何通过使用计算字段而其他字段不使用来进行组聚合?

可以使用聚合框架来获取所需的聚合,而不是使用group函数。考虑运行以下管道:

db.getCollection('expenses').aggregate([
    {
        "$project": {
            "day_created": { 
                "$dateToString": { 
                    "format": "%Y-%m-%d", 
                    "date": "$created" 
                } 
            },
            "user": 1
        }
    },
    {
        "$group": {
            "_id": {
                "day_created": "$day_created",
                "user": "$user"
            },
            "total": { "$sum": 1 }
        }
    },
    {
        "$project": {
            "_id": 0
            "user": "$_id.user",
            "day_created": "$_id.day_created",
            "total": 1
        }
    }
])

在上面的管道中,第一个 $project 步骤将使用 $dateToString 操作符创建day_created字段。下一个 $group 管道将根据两个键user和新创建的day_created字段对文档进行分组,并使用 $sum 计算聚合。

最后一个 $project 管道步骤然后重塑字段以输出所需的JSON结构。


要解决您的问题,您需要将created日期转换为唯一表示日期的日期格式。

尝试运行以下命令:

db.getCollection('expenses').group({
    keyf: function(doc) {
        var month = '' + (doc.created.getMonth() + 1),
        day = '' + doc.created.getDate(),
        year = doc.created.getFullYear();
        if (month.length < 2) month = '0' + month;
        if (day.length < 2) day = '0' + day;
        var day_created = [year, month, day].join('-');
        return { 
            "day_created": day_created,
            "user" : doc.user 
        }
    },
    cond: {},
    reduce: function (value, result) {
        result.total++;  
    },
    initial: {
        total: 0
    }
})

相关内容

  • 没有找到相关文章

最新更新