mongodb:查询两个日期字段之间的时间段

时间:2016-03-23 11:27:08

标签: mongodb mongodb-query aggregation-framework

如果我的mongoDB中保存了以下架构中的文档:

Note.objects.filter(user=user).distinct('tag').count()

是否可以查询创建和上次更新之间的时间段为例如文档。超过一天?

2 个答案:

答案 0 :(得分:6)

最佳选择是使用$redact聚合管道阶段:

db.collection.aggregate([
    { "$redact": {
        "$cond": {
            "if": {
                "$gt": [
                    { "$subtract": [ "$lastUpdate", "$createdDate" ] },
                    1000 * 60 * 60 * 24
                ]
            },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }}
])

因此,您正在查看差值的毫秒值,该值大于一天的毫秒值。 $subtract计算差异的数学运算,当减去两个日期时,返回毫秒数的差异。

$redact运算符将逻辑表达式作为“if”,并且该条件为true,它将“then”中的操作采用$$KEEP文档。如果是false,则会使用$$PRUNE从结果中删除该文档。

请注意,由于这是一个逻辑条件而不是设定值或值范围,因此不使用“索引”。

由于聚合管道中的操作是本机编码的,因此这是您可以获得的最快的执行语句。

替代方案是使用$where进行JavaScript评估。这需要一个JavaScript函数表达式,需要类似地返回truefalse值。在shell中你可以像这样简写:

db.collection.find(function() {
    return ( this.lastUpdate.valueOf() - this.createdDate.valueOf() )
       > ( 1000 * 60 * 60 * 24 );
})

同样的事情,除了JavaScript评估需要解释并且运行速度比.aggregate()等效的慢得多。出于同样的原因,这种类型的表达式不能使用索引来优化性能。

对于最佳结果,请将差异存储在文档中。然后你可以直接在该属性上查询,当然你也可以将其编入索引。

答案 1 :(得分:0)

您可以使用$expr(3.6 mongo版本运算符)在常规查询中使用聚合函数。

比较query operatorsaggregation comparison operators

db.col.find({$expr:{$gt:[{"$subtract":["$lastUpdate","$createdDate"]},1000*60*60*24]}})