我正在做一个相当复杂的聚合管道并且有一个相当奇怪的现象 - 我提取了一个简短的例子来形象化我的问题。
它似乎与MongoDb $addFields and $match有关 - 但它并不包含任何可以解决我们手头问题的信息。
注意:请注意我的问题不在于使用日期字段和处理值的具体示例,问题是我无法$match
使用表达式 - 使用之前添加的$addFields
字段。
鉴于MongoDB:3.6.3(目前最新)
让我们插入一些testdata:
db.testexample.insert({
"dateField": new ISODate("2016-05-18T16:00:00Z")
});
db.testexample.insert({
"dateField": new ISODate("2018-05-18T16:00:00Z")
});
现在让我们制作一个简单的管道,只计算日期的年份和$匹配:
db.testexample.aggregate([
{
"$addFields": {
"dateFieldYear": {"$year": "$dateField"}
}
},
{
"$match": {
"dateFieldYear": {"$eq": "$dateFieldYear"}}
}
}
])
- >没有比赛
它应匹配,因为它是同一个字段?也许有更多的诡计(使用$add
)?
db.testexample.aggregate([
{
"$addFields": {
"dateFieldYear": {"$year": "$dateField"}
}
},
{
"$match": {
"dateFieldYear": {"$eq": {"$add": ["$dateFieldYear", 0]}}
}
}
])
- >没有比赛
仍然没有骰子..接下来我认为变量完全是一个问题。因此,让我们修复这些值:
db.testexample.aggregate([
{
"$addFields": {
"dateFieldYear": {"$year": "$dateField"}
}
},
{
"$match": {
"dateFieldYear": {"$eq": {"$add": [2016, 0]}}
}
}
])
- >没有比赛
等等......这里出了点问题。让我们看一下静态值:
db.testexample.aggregate([
{
"$addFields": {
"dateFieldYear": {"$year": "$dateField"}
}
},
{
"$match": {
"dateFieldYear": 2016
}
}
])
- >找到1条记录!
所以我的结论似乎是 $match
无法对聚合管道中的字段进行表达。但这似乎不可能 - 因为文档指出$match
遵循查询语法as described here。
任何人都可以使用简单示例$match
来帮助"dateFieldYear": {"$eq": "$dateFieldYear"}}
如何完成此操作 - 为什么这不能按预期工作?
非常感谢您的帮助
答案 0 :(得分:2)
您可以使用$expr
(3.6 mongo版本运算符)在常规查询中使用聚合函数。
比较query operators
与aggregation comparison operators
。
在你的情况下
db.testexample.find({$expr:{$eq:["$dateFieldYear", "$dateFieldYear"]}})
常规查询:
db.testexample.find({$expr:{$eq:["$dateFieldYear", {"$year": "$dateField"}]}})
聚合查询:
db.testexample.aggregate({$match:{$expr:{$eq:["$dateFieldYear", {"$year": "$dateField"}]}})