mongodb聚合在日期时间键上

时间:2014-05-28 08:25:24

标签: mongodb aggregation-framework

我的文档由login_timelogout_time组成,我在其上设置了聚合,如下所示:

 db.connection_log.aggregate([{'$match':{"logout_time" : "2014-05-12 05:45:19"}},
{'$group': {'_id': {'ras_id': '$ras_id'},'total':  
{'$sum':{'$subtract':["$ISODate(logout_time)","$ISODate(login_time)"]}}}])

我的文件数据:

{'_id': ObjectId('5370982f1abbf80c21a3dd51'),
 '_type': 1,
 'caller_id': '',
 'credit_used': 0,
 'details': {'ip_assignment': false,
             'kill_reason': 'Killed by admin system',
             'mac': '',
             'persistent_lan': true,
             'user_id': NumberLong(805)},
 'login_time': '2014-05-12 05:44:37',
 'logout_time': '2014-05-12 05:45:19',
 'ras_id': 1,
 'retry_count': 1,
 'successful': true,
 'type_details': {'in_bytes': 0, 'out_bytes': 0, 'remote_ip': '10.0.0.1/32'},
 'unique_id': 'remote_ip',
 'unique_id_value': '10.0.0.1/32',
 'user_id': NumberLong(805),
 'username': 'ali'}

但它对我不起作用。 如何汇总我提交的日期? 请帮帮我。

1 个答案:

答案 0 :(得分:0)

你在这里遇到的一个大问题是你的“约会”实际上是字符串。您需要将它们作为日期类型。所以用JavaScript shell形式来修复脚本:

db.connection_log.find({},{ "login_time": 1, "logout_time": 1}).forEach(
    function(doc) {
        db.connection_log.update(
            { "_id": doc._id },
            {
                "$set": { 
                    "login_time": new ISODate( doc["login_time"] ),
                    "logout_time": new ISODate( doc["logout_time"] )
                }
            }
        );
    }
)

然后你可以正确聚合:

db.connection_log.aggregate([
    { "$match":{ "logout_time" : ISODate("2014-05-12 05:45:19") }},
    { "$group": {
        "_id": "$ras_id",
        "total": { 
            "$sum":{
                "$subtract":[
                    "$logout_time",
                    "$login_time"
                ]
            }
        }
    }}
])

这样实际上会给你一个抽象的结果,作为时间之间“毫秒”的纪元时间戳值差。这是一个整数,你可以$sum

另请参阅this recent answer了解更新收藏集的有效方法。