我正在创建一个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
}
}
]
)
但是,第二个查询工作:
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
}
}
]
)
我需要在$subtract
块上使用$match
,因此我无法使用上一个查询。
答案 0 :(得分:2)
$subtract
运算符是投影运算符。它仅在$project
步骤中可用。所以你的选择是:
timestamp
字段。我不建议您这样做,因为需要对数据库上的每个文档执行此操作,并阻止数据库在时间戳字段上使用索引,因此可能会花费很多性能。答案 1 :(得分:2)
嗯,你做不到这一点,你也不打算这样做。另一个有效的方面是你说“需要”这样做,但实际上你真的没有。
aggregation operators之外的所有常规pipeline operators实际上只在$project
或$group
管道阶段有效。大部分在$project
范围内,但肯定不在其他范围内。
$match
管道与普通"query"操作实际上是相同的,因此唯一有效的内容是query operators。
对于“需要”的情况,在将BSON表示发送到实际管道之前,需要在实际管道之外评估在聚合管道内提交的任何“值”,特别是在$match
内。服务器
唯一的例外是在文档中定义变量的符号,特别是“{1}}中的”字段名称“,然后才真正在"$fieldname"
或$project
中。所以这意味着“引用”文档的现有值,这是在任何类型的“查询”文档表达式中无法完成的事情。
如果您需要使用文档中其他字段的值,则首先使用$group
进行处理,如下所示:
$project
出于任何其他目的,您真的想要评估管道“外部”的值。
上面回答了你问的问题,但这回答了你没有问的问题。
您的管道没有任何意义,因为单独对“时间戳”进行分组不太可能对任何内容进行分组,因为这些值的精确度为毫秒级,并且对于非常活跃的系统而言,最多可能不会超过几个
看起来你正在寻找按“天”分组的数学,你可以这样做:
db.collection.aggregate([
{ "$project": {
"fieldMath": { "$subtract": [ "$fieldOne", "$fieldTwo" ] }
}},
{ "$match": { "fieldMath": { "$gt": 2 } }}
])
将您的时间戳值“舍入”到一天,并且比其他方式更有可能“聚合”某些东西。
或者你可以使用"date aggregation operators"对复合键做同样的事情。
因此,如果您想“查询”,那么它会在外部进行评估。如果要处理“文档内”的值,则必须在db.collection.aggregate([
{ "$group": {
"_id": {
"$subtract": [
{ "$subtract": [ "$timestamp", new Date(0) ] },
{ "$mod": [
{ "$subtract": [ "$timestamp", new Date(0) ] },
1000 * 60 * 60 * 24
]}
]
},
"total": { "$sum": "$total" }
}}
])
或$project
管道阶段执行此操作。
答案 2 :(得分:0)
从mongodb 3.6开始,您可以在$ match阶段通过$ expr使用$ subtract。这是文档:https://docs.mongodb.com/manual/reference/operator/query/expr/
我可以通过$ expr和mongodb 4.2中一个名为$$ NOW的新系统变量来获取类似您所描述的查询。这是我的查询,它向我提供最近4个小时内创建的订单:
create table user_chapters(
chapter_id serial primary key,
chapter_content varchar)