【问题标题】:MongoDB Aggregation Pipeline: $match with expression not possible?MongoDB 聚合管道:$match 与表达式不可能?
【发布时间】:2018-08-23 00:21:17
【问题描述】:

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

它似乎与 MongoDb $addFields and $match 相关 - 但它不包含任何信息让我解决手头的问题。

注意:请注意,我的问题不在于使用日期字段和/或处理值的具体示例,问题是我无法使用表达式 $match -是否使用之前添加的字段 $addFields

给定 MongoDB:3.6.3(当前最新)

让我们插入一些测试数据:

db.testexample.insert({
   "dateField": new ISODate("2016-05-18T16:00:00Z")
});

db.testexample.insert({
   "dateField": new ISODate("2018-05-18T16:00:00Z")
});

现在让我们创建一个简单的管道,它只计算日期的年份和 $matches:

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

任何人都可以使用简单的示例"dateFieldYear": {"$eq": "$dateFieldYear"}} 来帮助如何处理$match - 为什么这不能按预期工作?

非常感谢您的帮助

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    您可以使用$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"}]}})
    

    【讨论】:

    • Aaaah 是的.. 我一发布问题,我就在文档中看到了 $expr ;-).. 应该仔细看看.. 谢谢
    • 我们可以在 $expr 中应用 2 个条件吗?我的意思是如果日期匹配 vand 和状态?
    • @KishorPatidar 查看 $and 运算符
    猜你喜欢
    • 2015-04-24
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 2014-12-11
    • 2015-04-06
    • 2020-07-09
    相关资源
    最近更新 更多