Mongo $subtract 日期在聚合 $match 块中不起作用

ind*_*aep 5 mongodb nosql mongodb-query aggregation-framework

我正在创建一个 mongo 聚合查询,它在我的 $match 块中使用 $subtract 运算符。正如下面这些代码中所解释的。

此查询不起作用:

db.coll.aggregate(
[
    {
        $match: {
            timestamp: {
                $gte: {
                    $subtract: [new Date(), 24 * 60 * 60 * 1000]
                }
            }
        }
    },
    {
        $group: {
            _id: {
                timestamp: "$timestamp"
            },
            total: {
                $sum: 1
            }
        }
    },
    {
        $project: {
            _id: 0,
            timestamp: "$_id.timestamp",
            total: "$total",
        }
    },
    {
        $sort: {
            timestamp: -1
        }
    }
]
)
Run Code Online (Sandbox Code Playgroud)

但是,第二个查询有效:

db.coll.aggregate(
[
    {
        $match: {
            timestamp: {
                $gte: new Date(new Date() - 24 * 60 * 60 * 1000)
            }
        }
    },
    {
        $group: {
            _id: {
                timestamp: "$timestamp"
            },
            total: {
                $sum: 1
            }
        }
    },
    {
        $project: {
            _id: 0,
            timestamp: "$_id.timestamp",
            total: "$total",
        }
    },
    {
        $sort: {
            timestamp: -1
        }
    }
]
)
Run Code Online (Sandbox Code Playgroud)

我需要$subtract在我的$match块上使用,所以我不能使用最后一个查询。

Chr*_*ton 6

从 mongodb 3.6 开始,您可以通过 $expr 在 $match 阶段使用 $subtract。这是文档:https : //docs.mongodb.com/manual/reference/operator/query/expr/

我能够通过此 $expr 和 mongodb 4.2 中名为 $$NOW 的新系统变量获得类似于您所描述的查询。这是我的查询,它为我提供了过去 4 小时内创建的订单:

[ 
 { $match: 
  { $expr: 
   { $gt: [ 
    "$_created_at", 
     { $subtract: [ "$$NOW", 4 * 60 * 60 * 1000] } ] 
   } 
  } 
 }
]
Run Code Online (Sandbox Code Playgroud)


Phi*_*ipp 3

$subtract运算符是投影运算符。它仅在$project步骤期间可用。所以你的选择是:

  • (不推荐)在 $match-step 之前添加 $project-step 来转换timestamp以下 match-step 的所有文档的字段。我不建议您这样做,因为此操作需要对数据库中的每个文档执行,并且会阻止数据库在时间戳字段上使用索引,因此可能会消耗大量性能。
  • (推荐)在 shell/应用程序中生成要匹配的日期。生成一个新的 Date() 对象,将其存储在变量中,从中减去 24 小时,然后使用该变量执行第二个查询。