基于一组条件从嵌套数组中提取MongoDB$pull

基于一组条件从嵌套数组中提取MongoDB$pull,mongodb,Mongodb,好的,我希望更新与以下查询匹配的所有文档: var searchArray = ["AH Refer" ]; db.ReasonTest.find({ $and: [ { "Values.Reason": { $in: searchArray } }, { "Values.Modules": { $all: ["Provider Search"] }

好的,我希望更新与以下查询匹配的所有文档:

var searchArray = ["AH Refer"
];
db.ReasonTest.find({ 
$and: [
    {
        "Values.Reason": {
            $in: searchArray
        }
    },
    {
        "Values.Modules": {
            $all: ["Provider Search"]
        }
    }
]
});
我的文档结构如下所示:

{
"_id" : ObjectId("537398e92db5868b145f5f29"),
"ID" : NumberLong(1),
"Name" : "MCC",
"Values" : [ 
    {
        "ID" : NumberLong(1016),
        "Reason" : "COB",
        "Modules" : [ 
            "SRA"
        ]
    }, 
    {
        "ID" : NumberLong(104),
        "Reason" : "AH Refer",
        "Modules" : [ 
            "Provider Search"
        ]

    }
]
}

基本上,我想做的是查找所有原因(根文档),它在值数组的原因字段中有上面的一个值(例如“AH refere”)。如果模块数组中有“Provider Search”,我想从模块数组中删除“Values”中该值的“Provider Search”。对于这个客户来说,我的日子真的很难过。显然,它们的结构并不理想(Mongo中的嵌套数组支持不是很好),但我希望你们中的一个wizkids可以帮助我。提前感谢!:)

根据问题底部的描述, 我对查询部分的理解是:
原因
模块
都符合条件 在相同的“值”元素中,则文档是需要更新的。 因此,我用
$elemMatch
相应地修改了查询部分

var searchArray = [ "AH Refer to CMC: Claims Inquiry",
        "AH Refer to CMC:  Eligibility Inquiry",
        "AH Refer to CMC: Requested Benefit Information",
        "After Hours - Referred to CMC", "After Hours Referred to RHBA" ];

var moduleValue = "Provider Search";

while (db.ReasonTest_Kyle.update({
    Values : {
        $elemMatch : {
            Reason : {
                $in : searchArray
            },
            Modules : moduleValue
        }
    }
}, {
    $pull : {
        "Values.$.Modules" : moduleValue
    }
}, {
    multi : true
}).nModified);
当nModified==0时,所有文档都已修改,循环退出。
上述代码的缺点是:可能需要多次更新同一文档。
但它是线程安全的


追加 以下代码与V2.6之前的MongoDB版本兼容

var searchArray = [ "AH Refer to CMC: Claims Inquiry",
        "AH Refer to CMC:  Eligibility Inquiry",
        "AH Refer to CMC: Requested Benefit Information",
        "After Hours - Referred to CMC", "After Hours Referred to RHBA" ];

var moduleValue = "Provider Search";

var query = {
        Values : {
            $elemMatch : {
                Reason : {
                    $in : searchArray
                },
                Modules : moduleValue
            }
        }
    };

var nCallUpdate = 0;

while ( db.ReasonTest_Kyle.findOne(query, {_id :1}) ) {
    db.ReasonTest_Kyle.update(query, {
        $pull : {
            "Values.$.Modules" : moduleValue
        }
    }, {
        multi : true
    });
    nCallUpdate++;
}
     

我得到一个错误,说结果没有属性?此外,我看到的行为与我的解决方案产生的行为相似。它从它匹配的第一个模块中删除“提供者搜索”模块,但是它应该删除的所有其他模块仍然存在。我注意到您提到的这可能需要运行多次。你能解释一下为什么会这样吗?@Kyle Richter,你能把完整的错误信息粘贴到这里吗?@Kyle Richter,我测试了我的代码,效果很好。我猜您的MongoDB版本低于2.6,这导致了。不支持nmodied。@Kyle Richter,
db.c.update({},{})
将最多修改该数组的一个元素。因此,在您的情况下,如果有3个元素符合查询条件,则必须更新3次。这就是为什么我使用while语句。