MongoDB聚合管道:$匹配表达式不可能?

时间:2018-03-14 12:53:26

标签: mongodb aggregation-framework

我正在做一个相当复杂的聚合管道并且有一个相当奇怪的现象 - 我提取了一个简短的例子来形象化我的问题。

它似乎与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"}}如何完成此操作 - 为什么这不能按预期工作?

非常感谢您的帮助

1 个答案:

答案 0 :(得分:2)

您可以使用$expr(3.6 mongo版本运算符)在常规查询中使用聚合函数。

比较query operatorsaggregation 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"}]}})