如何简化此聚合框架查询(使用日期格式和比较)

时间:2014-12-15 17:48:02

标签: mongodb aggregation-framework

我已经有了我需要的工作查询(包括在下面),但我无法帮助,但我觉得必须有更好的方法来实现这一目标。我的要求相当简单,但结果查询本身就是流眼代码的定义。

这是我们正在迭代的示例文档(删除了不相关的属性):

> db.Thing.find().limit(1).pretty()
{
    "_id": ObjectId(...),
    "created": ISODate(...),
    "updated": ISODate(...)
}

我对查询的要求是:

  • 仅匹配created > updated
  • 的内容
  • YYYY-MM字段的created值进行分组,并减少为计数。
  • 输出应如下所示:
    { "count": 93592, "month": "2014-06" },
    { "count": 81629, "month": "2014-07" },
    { "count": 126183, "month": "2014-08" },
    ...

同样,这个感觉就像它应该真的简单。这是我正确运行的查询,目前正在执行此操作:

db.Thing.aggregate([
    { $project: {
        cmpDates: { $cmp: ['$created', '$updated'] },
        created: '$created'
    }},
    { $match: {
        cmpDates: { $ne: 0 }
    }},
    { $project: {
        month: {
            $concat: [
                { $substr: [ { $year: '$created' }, 0, 4 ] },
                '-',
                { $cond: [
                    { $lte: [ { $month: '$created' }, 9 ] },
                    { $concat: [
                        '0',
                        { $substr: [ { $month: '$created' }, 0, 2 ] }
                    ]},
                    { $substr: [ { $month: '$created' }, 0, 2 ] }
                ] }
            ]
        },
        _id: 0
    }},
    { $group: {
        _id: '$month',
        count: { $sum: 1 }
    }},
    { $project: {
        month: '$_id',
        count: 1,
        _id: 0
    }},
    { $sort: { month: 1 } }
]);

我的问题:此查询可以简化,如果是,如何?

谢谢!

1 个答案:

答案 0 :(得分:1)

试试这个:

db.test.aggregate([
    { "$project" : { 
        "cmpDates" : { "$cmp" : ["$created", "$updated"] }, 
        "createdYear" : { "$year" : "$created" }, 
        "createdMonth" : { "$month" : "$created" } 
    } }, 
    { "$match" : { "cmpDates" { "$ne" : 0 } } },
    { "$group" : { 
        "_id" : { "y" : "$createdYear", "m" : "$createdMonth" }, 
        "count" : { "$sum" : 1 } 
    } }
])

最大的区别在于我为组使用了复合键,因此我将对(year, month)进行分组,而不是构造字符串值YYYY-MM以实现相同的目的。