Mongodb 使用$project和$match的MongDB聚合

Mongodb 使用$project和$match的MongDB聚合,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有类似以下文件: {_id:'12345', timestamp:41123412451, value:1000} {_id:'98765', timestamp:41123498714, value:2000} {_id:'11122', timestamp:41287364245, value:3000} [ {$match: {_id: {$ne: ObjectId('98765')}}}, {$project: { duration:{$subtract:[Date.now()

我有类似以下文件:

 {_id:'12345', timestamp:41123412451, value:1000}
 {_id:'98765', timestamp:41123498714, value:2000}
 {_id:'11122', timestamp:41287364245, value:3000}
[
{$match: {_id: {$ne: ObjectId('98765')}}},
{$project: { duration:{$subtract:[Date.now(),'$timestamp']}, value:1, _id:1}},
{$match:{value:{$gte:'duration'}}}
]
我正在运行一个聚合查询,类似于:

 {_id:'12345', timestamp:41123412451, value:1000}
 {_id:'98765', timestamp:41123498714, value:2000}
 {_id:'11122', timestamp:41287364245, value:3000}
[
{$match: {_id: {$ne: ObjectId('98765')}}},
{$project: { duration:{$subtract:[Date.now(),'$timestamp']}, value:1, _id:1}},
{$match:{value:{$gte:'duration'}}}
]
当我删除第二个$match时,我会得到除“98765”(如预期)之外的所有文档。但是,当我包含第二个$match时,我没有得到任何文档。我试过“duration”和“$duration”。当我将第二个匹配中的“duration”替换为硬编码的数字值(如0)时,查询将按需要工作(通过过滤掉值不大于或等于0的文档)

似乎有一些“类型”问题正在发生,mongo正在默默地忽略,不返回任何东西。。。有人能指出我在使用上述聚合方法时可能遗漏了什么吗???谢谢

聚合阶段不是这样工作的。与标准查询一样,您不能将字段的值引用到另一个字段的查询运算符。有,它们与舞台一起使用,比如:

{“$project”:{
“持续时间”:{“$subtract”:[Date.now(),“$timestamp”]},
“价值”:1,
“匹配”:{“$gte”:[“$value”,{“$subtract”:[Date.now(),“$timestamp”]}
}},
{“$match”:{“matched”:true}
但实际上,这可能是更好的和“有选择地”投影您的新领域:

{“$redact”:{
“$cond”:{
“如果”{“$gte”:[“$value”,{“$subtract”:[Date.now(),“$timestamp”]}],
“然后”:“$$KEEP”,
“else”:“$$PRUNE”
}
}},
{“$project”:{
“持续时间”:{“$subtract”:[Date.now(),“$timestamp”]},
“价值”:1
}},
因此,
$redact
以“逻辑”的方式工作,其意义与
$match
以“物理”的方式工作相同,并且可以包括可以对文档进行计算值或直接字段比较以“过滤”内容的表达式


这样做基本上也很方便,因为
$project
的成本实际上仅限于满足条件的文档,如果您甚至需要输出中的计算值,那么您可以完全跳过它。

您在第二次匹配查询中犯了一个简单的错误

 {$match:{value:{$gte:'duration'}}}
应该是:

{$match:{value:{$gte:'$duration'}}}

持续时间””是聚合管道第二阶段生成的变量。因此,在第三阶段,它应该被称为“$duration”。

@ossys Typo?我只看了《the》。这是不是让这个无效?@ossys我想在你评论之前,你可能需要看看答案上的“编辑历史记录”。您的评论“暗示”答案中“添加”了
$redact
语句,但它始终存在。“添加”的只是一段对正在发生的事情的解释。请注意,这也不能排除初始的
$match
,因为该或另一个真正的“查询”阶段应该始终是任何管道操作的第一个阶段,因为它是一个可以使用索引的真正过滤器。