【问题标题】:How to query subdocument array using value in main document如何使用主文档中的值查询子文档数组
【发布时间】:2017-06-29 18:41:51
【问题描述】:

我有一个包含一些属性的文档,其中一个属性是子文档数组,我想查找文档并将主文档中的属性与子文档数组中的属性进行比较

以下是文档示例

{
"_id" : ObjectId("54bb897d52a8a302ecafeb03"),
“Contract" : “ABCDE",
“OptimalYear" : 2012,
"Results" : [ 

    {
        "Year" : 2011,
        "Risk" : 1114
    }, 
    {
        "Year" : 2012,
        "Risk" : 1226
    }, 
    {
        "Year" : 2013,
        "Risk" : 1385.5
    }
]
}

我可以的

db.CC.find({
Contract: "Jan",
Result: {
    $elemMatch: {
        Year: 2012
    }
}
})

但是我将如何在 $elemMatch {Year: OptimalYear} 中使用 OptimalYear 的值

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您无法使用标准查询来执行此操作,或者大多数人实际要求的是在处理更新时引用文档中字段的值。没有允许在这些查询中引用字段值的语法。

    您可以通过聚合框架来做到这一点。自 MongoDB 2.6 以来的现代版本具有 $redact 管道阶段,它有一种很好的处理方式:

    db.collection.aggregate([
        { "$redact": {
            "$cond": {
                "if": {
                    "$eq": [
                        { "$ifNull": [ "$Year", "$$ROOT.OptimalYear" ] },
                        "$$ROOT.OptimalYear"
                    ]
                },
                "then": "$$DESCEND",
                "else": "$$PRUNE"
            }
        }}
    ])
    

    这基本上评估$cond 条件或三元语句以查看值实际匹配的位置,然后您将保留该元素。否则当前文档级别将被删除。

    $ifNull 与对$$ROOT 的引用一起存在,因为这是通过结构递归的。例如,文档顶部没有“Year”字段,因此比较替换为“OptimalYear”值。与自己比较返回 true,但在数组中,它将与存在的“年份”进行比较。

    在早期版本中仍然可以这样做,但确实需要更多的工作,因此不是最佳方式:

    db.collection.aggregate([
        { "$unwind": "$Results" },
        { "$project": {
            "Contract": 1,
            "OptimalYear": 1,
            "Results": 1,
            "matched": { "$eq": [ "$Results.Year", "$OptimalYear" ] }
        }},
        { "$match": { "matched": true } },
        { "$group": {
            "_id": "$_id",
            "Contract": { "$first": "$Contract" },
            "OptimalYear": { "$first": "$OptimalYear" },
            "Results": { "$push": "$Results" }
        }}
    ])
    

    不完全相同,因为它完全过滤掉没有匹配的文档,您也可以在以前的版本中通过添加额外的$match 阶段来检查空数组。

    【讨论】:

      猜你喜欢
      • 2014-08-27
      • 2021-04-28
      • 1970-01-01
      • 2020-07-16
      • 2016-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多