Mongodb 如何使用主文档中的值查询子文档数组

Mongodb 如何使用主文档中的值查询子文档数组,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一个文档,它有几个属性,其中一个属性是子文档数组,我想查找文档并将主文档中的属性与子文档数组中的属性进行比较 下面是该文档的一个示例 { "_id" : ObjectId("54bb897d52a8a302ecafeb03"), “Contract" : “ABCDE", “OptimalYear" : 2012, "Results" : [ { "Year" : 2011, "Risk" : 1114 }, {

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

下面是该文档的一个示例

{
"_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 2.6以来的现代版本都有管道阶段,这是一种很好的处理方法:

db.collection.aggregate([
{“$redact”:{
“$cond”:{
“如果”:{
“$eq”:[
{“$ifNull”:[“$Year”,“$$ROOT.optimizeyear”]},
“$$ROOT.YEAR”
]
},
“然后”:“$$down”,
“else”:“$$PRUNE”
}
}}
])
这基本上是对条件语句或三元语句求值,以查看值实际匹配的位置,然后保留元素。否则,将删除当前文档级别

由于它是通过结构递归的,所以它与对的引用一起存在。例如,文档顶部没有“年”字段,因此比较将替换为“最优年”值。与您自己进行比较返回true,但在数组中,它将与存在的“年”进行比较

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

db.collection.aggregate([
{“$REWIND”:“$Results”},
{“$project”:{
“合同”:1,
“最佳年份”:1,
"成果":一,,
“匹配”:{“$eq”:[“$Results.Year”,“$optimizeyear”]}
}},
{“$match”:{“matched”:true},
{“$组”:{
“\u id”:“$\u id”,
“合同”:{“$first”:“$CONTACT”},
“优化年”:{“$first”:“$OPTIMEATIONYEAR”},
“结果”:{“$push”:“$Results”}
}}
])
不完全相同,因为这是完全过滤掉不匹配的文档,您也可以在以前的版本中通过添加额外的阶段来检查空数组来实现这一点