英文:
Dynamic MongoDB aggregation using $$NOW
问题
同行们;
是否有人能够友善地解释一下这个问题,这个问题已经困扰我几天了?这应该是一件简单的事情,但我似乎找不到问题出在哪里...
我需要从一个集合中检索一年的记录,根据今天的日期。简而言之,如果今天是2023-02-15,我需要检索2022-02-15之后创建的记录。
这当然可以工作:
[
{
$match: { _created: { $gte: ISODate("2022-02-15") } }
}
]
问题在于,当尝试创建一个不需要不断更新的聚合时,$$NOW
似乎不起作用,我无法理解为什么。
例如,这个不起作用:
[
{
$match:
{
_created:
{
$gte:
{
$subtract: [ "$$NOW", { $multiply: [1000, 60, 60, 24, 365] } ]
}
}
}
}
]
这个也不起作用:
[
{
$set:
{
startDate: { $subtract: [ "$$NOW", { $multiply: [1000, 60, 60, 24, 365] } ] }
}
},
{
$match:
{
_created: { $gte: ISODate("$startDate") }
}
}
]
我尝试过移动元素,解析 $$NOW
的结果以获取只有日期部分,将其转换为不同的类型... 结果总是一样的:没有错误,但也没有筛选记录。
我有一种感觉,答案可能是我正在忽略的一些非常愚蠢的东西。
有更有经验的人能伸出援手吗?
附言:在检索所需的记录后,聚合会继续,我只是没有列出发生的事情,因为问题只涉及记录的匹配。我们的 Mongod 版本是 6.0.3,我正在使用 MongoDB Compass,想法是将这个聚合保存为一个查询,以响应 API 调用提供答案。
英文:
Fellows;
Would anyone be so kind as to shed a light on this matter which has been stumping me for a few days now? It should be something simple, but I can't seem to find where the problem lies...
I need to retrieve one year worth of records from a collection based on today's date. Simply put, if today is 2023-02-15, I need records created after 2022-02-15.
This works, of course:
[
{
$match: { _created: { $gte: ISODate("2022-02-15") } }
}
]
The problem is that, when trying to create an aggregation that does not need to constantly be updated, $$NOW does not seem to work and I cannot understand why.
For example, this does not work:
[
{
$match:
{
_created:
{
$gte:
{
$subtract: [ "$$NOW", { $multiply: [1000, 60, 60, 24, 365] } ]
}
}
}
}
]
And this doesn't either:
[
{
$set:
{
startDate: { $subtract: [ "$$NOW", { $multiply: [1000, 60, 60, 24, 365] } ] }
}
},
{
$match:
{
_created: { $gte: ISODate("$startDate") }
}
}
]
I have tried moving things around, parsing the result of $$NOW to get just the date part, converting it to different types... The result is always the same: No errors, but no filtered records either.
And I have the feeling the answer might be something really silly I am just overlooking.
Can someone more experienced lend a helping hand?
P.S.: The aggregation continues after the required records are retrieved, I just did not care to list what happens because the problem relates only to the matching of records. Our Mongod version is 6.0.3, I am working on MongoDB Compass and the idea is to save this aggregation as a query which provides answers to an API call.
答案1
得分: 2
你需要使用$expr
和$gte聚合运算符(不要与$gte查询运算符混淆)。在MongoDB 5.0及更新版本中,你还可以使用日期表达式运算符,比如$dateSubtract
。
{
$match:
{
$expr:
{
$gte:
[ "$_created", { $dateSubtract: { startDate: "$$NOW", unit: "year", amount: 1 } } ]
}
}
}
英文:
You need to use $expr
and $gte aggregation operator (do not mistake with $gte Query Operator). In MongoDB 5.0 and newer, you can also use Date Expression Operators like $dateSubtract
{
$match:
{
$expr:
{
$gte:
[ "$_created", { $dateSubtract: { startDate: "$$NOW", unit: "year", amount: 1 } } ]
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论