MongoDB聚合管道计算保留

时间:2016-11-29 08:25:37

标签: mongodb mongodb-query aggregation-framework

我有一组用户。所有用户都有createdAtlastLogin字段。 createdAt字段是表示用户注册时间的日期,lastLogin字段是表示用户上次登录网站的日期。

我想知道2月份注册的用户在注册后至少30天再次登录该网站。除此之外,我想了解一下在3月,4月,5月等注册的用户在首次注册后至少30天内签名的用户。

我有一个类似的(但不同的)方法,计算出过去30天内每月有多少人登录(其中fromDate是30天前) :

const pipeline = [
    {
        $match: {
            lastLogin: {
                $gt: fromDate,
                $exists: true
            },
        },
    }, 
    {
        $group: {
            _id: {
                year : { $year : "$createdAt" },
                month : { $month : "$createdAt" },
            },
            sum: { $sum: 1 }
        }
    }
];

但我不知道如何改变它来做我想做的事。

我想要做的是计算在2月1日注册的人数在3月1日之后的任何时间点登录。 第二个查询的作用是计算在过去30天内有多少人在2月份注册了。因此,如果今天是10月1日,它将计算从9月1日开始登记的所有人。

1 个答案:

答案 0 :(得分:1)

尝试使用map-reduce查询,我认为这就是您所需要的:

// Al 3 users were createdAt februrary 2016
db.collection.save([
    {createdAt: new Date(2016, 1, 2), lastLogin: new Date(2016, 2, 5)},
    {createdAt: new Date(2016, 1, 3), lastLogin: new Date(2016, 2, 7)},
    {createdAt: new Date(2016, 1, 2), lastLogin: new Date(2016, 1, 15)},
])


map = function() { 
    var days30after = new Date(this['createdAt']);
    days30after.setDate(this['createdAt'].getDate()+30);

    if(this['lastLogin'] >= days30after){

        // Group results based on year and month values, add 1 to month
        var key = {'year':this['createdAt'].getUTCFullYear(), 'month':this['createdAt'].getUTCMonth()+1};
        emit(key, 1);   
    }
}

reduce = function(key, values) {
    return values.length;
} 

db.collection.mapReduce(map,reduce, { out : "collection2" });

db.collection2.find().pretty()

结果:2名用户在2月份注册并在30天后再次注册

{ "_id" : { "year" : 2016, "month" : 2 }, "value" : 2 }
相关问题