如何按键过滤,按日期范围查找,然后在mongodb中按周汇总?

时间:2017-03-14 03:52:24

标签: mongodb mongodb-query aggregation-framework

我有一个名为MyCollection的mongo集合,它包含如下文档:

{ 
    "_id" : ObjectId("58085384e4b0f70605461e3f"), 
    "uid" : "fa1aeafc-18db-41a5-8ee5-ac0c32428fe1",
    "Key1" : "Value1"  
    "timeStamp" : ISODate("2016-08-23T17:58:20.000+0000"), 
}

部分文件有Key1,而其他文件有Key2Key3

现在,我希望做到以下几点: -

  1. 仅获取包含Key1Key2
  2. 的文档
  3. 从上面得到的一组文档中,只获取timeStamp范围Date(2016, 08, 01)Date(2016, 08, 31)范围内的文档。
  4. 对于上面得到的文档集,请按周汇总。
  5. 如何为此编写mongo查询?

2 个答案:

答案 0 :(得分:1)

试试这个:

db.collection.find(
{$or:[{"key1":{$exists:true}},{"key2":{$exists:true}}],
timeStamp: {$gte: Date(2016, 08, 01), $lte:Date(2016, 08, 31)}
})

上面的查询符合你的1和2条件。你完全不了解你的第3个条件,请详细说明。

答案 1 :(得分:1)

使用聚合框架,可以使用 $match $group 管道步骤完成上述步骤,如下所示:

var start = new Date(2016, 7, 1), // months are zero-based indexes i.e Aug month index is 7
    end = new Date(2016, 7, 30); // August month ends on the 30th

db.collection.aggregate([
    { /* filter steps 1 & 2 */
        "$match": {
            "$or": [
                { "Key1": { "$exists": true } },
                { "Key2": { "$exists": true } }
            ],
            "timeStamp": { "$gte": start, "$lte": end }
        }
    },
    { /* group by week */ 
        "$group": {
            "_id": { "$week": "$timeStamp" },
            "count": { "$sum": 1 },
            "uids": { "$push": "$uid" }
        }
    }
])

在上文中,日期范围是使用 Date() 构造函数创建的,其中月份是从零开始的索引。 $exists 运算符用于确定密钥的存在,并使用 $week 日期汇总运算符来获取日期之间的周数0(在一年的第一个星期日之前的部分周)和53(闰年)。

对于包含年份第一个星期四的星期(星期一到星期日)从1开始的星期数,MongoDB 3.4及更新版提供 $isoweek 运算符供使用。