如何在mongodb过滤器中使用计算出的日期?

时间:2018-12-26 19:00:59

标签: mongodb mongodb-query aggregation-framework

我要过滤最后一分钟内的文档。但是以下具有计算的$gte时间的查询不起作用。

db.mycollection.aggregate([
    {$match: {
       "properties.time": {$gte: {$subtract: [ISODate(), 60000]}}
    }}
])

它不会返回任何内容,但不是因为最后一分钟内没有日期。从我可以预测的确实可以查询的查询中计算出的日期来看,计算出的日期是正确的。是否有某些原因导致您不能以这种方式使用计算值?

以下具有硬编码时间的查询确实有效:

db.mycollection.aggregate([
    {$match: {
       "properties.time": {$gte: ISODate("2018-12-26T12:00:00Z")}
    }}
])

我还考虑了以秒为单位计算年龄,然后根据该年龄进行过滤。以下内容也可以。

db.mycollection.aggregate([
    {$project: {
        "properties.time": "$properties.time",
        "age": {$subtract: [ISODate(), "$properties.time"]}
    }},
    {$match: {
        "age": {$lte: 60000}
    }}
])

但这不是一个好的解决方案,因为

  • 是的,我确实想在$geoNear查询中包含过滤器,并且由于$geoNear必须是管道中的第一步,所以我无法预测年龄然后使用在$geoNear

  • 我想使用"properties.time"

  • 上的索引

我们正在使用eve,因此另一个解决方法是将请求的max_age参数转换为钩子中的start_time。但实际上似乎第一种方法应该可行。

1 个答案:

答案 0 :(得分:1)

您正在$match内部使用聚合expression,因此必须使用$expr运算符,请尝试:

db.mycollection.aggregate([
    {
        $match: {
            $expr: {
                $gte: [ "$properties.time", { $subtract: [ISODate(), 60000] } ]
            }
        }
    }
])

对于低于3.6的MongoDB,您可以使用$redact作为后备,请尝试:

db.mycollection.aggregate([
    {
        $redact: {
            $cond: {
                if: { $gte: [ "$properties.time", { $subtract: [ISODate(), 60000] } ] },
                then: "$$KEEP",
                else: "$$PRUNE"
            }
        }
    }
])