Mongodb $拉上嵌套文档

时间:2014-10-16 08:39:03

标签: mongodb mongodb-query

我有一个像这样的集合records

{
    "recordId" : "5a65d212-774e-4208-8cb4-bf4e92e80898",
    "recordName" : "recordABC",
    "entries" : [
        {
            "formId" : "f548684e-31a7-4e63-af5c-4120670f963f",
            "formSequence" : 1,
            "fieldId" : "element1",
        },
        {
            "formId" : "f548684e-31a7-4e63-af5c-4120670f963f",
            "formSequence" : 2,
            "fieldId" : "element2",
            "value" : "notes"
        },
        {
            "formId" : "f548684e-31a7-4e63-af5c-4120670f963f",
            "formSequence" : 1,
            "fieldId" : "element3",
            "value" : [
                {
                    "originalFileName" : "fileA",
                    "thumbnail" : "thumbnailA"
                },
                {
                    "originalFileName" : "fileB",
                    "thumbnail" : "thumbnailB"
                },
                {
                    "originalFileName" : "fileC",
                    "thumbnail" : "thumbnailC"
                },
                {
                    "originalFileName" : "fileD",
                    "thumbnail" : "thumbnailD"
                }
            ]
        }
    ]
 }

我需要删除文档

{
    "originalFileName" : "fileC",
    "thumbnail" : "thumbnailC"
}

来自record.entries.value数组。

我尝试使用以下查询

db.records.update({ "_id" : "5a65d212-774e-4208-8cb4-bf4e92e80898" , $and : [ { "entries.formSequence" : 1} , { "entries.formId" : "f548684e-31a7-4e63-af5c-4120670f963f"} , { "entries.fieldId" : "element3"}]}, { $pull : { "entries.$.value" : { "originalFileName" : "fileC"}}});

返回WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 }) 有一个匹配,但"originalFileName" : "fileC"的项目未被删除

我的查询有什么问题?怎么做?

1 个答案:

答案 0 :(得分:1)

在update语句中使用positional $运算符时,需要确保匹配数组中的特定元素。 $and通常不会删除它,数组元素的多个字段所需的是$elemMatch

db.records.update(
    { 
        "recordId": "5a65d212-774e-4208-8cb4-bf4e92e80898", 
        "entries": {
            "$elemMatch": { 
                "formSequence": 1,
                "formId" : "f548684e-31a7-4e63-af5c-4120670f963f",
                "fieldId" : "element3"
             }
        }
    }, 
    { 
        "$pull" : { 
            "entries.$.value" : { "originalFileName" : "fileB"}
        }
    }
)

这确保了"位置"匹配运算符的匹配是匹配所有的运算符,用于指定的元素属性的条件。

在这种情况下$and的主要问题(也没有必要,因为你没有在同一个字段上要求多个条件,所以它实际上是一个隐式语句,MongoDB只是这样做是因为你没有匹配相同元素的条件。所做的一切就是确保所有条件实际匹配文档中某处,因此确保任何元素。

您也可以这样写,这不会返回正确的结果:

db.records.update(
    { 
        "recordId": "5a65d212-774e-4208-8cb4-bf4e92e80898", 
        "entries.formSequence": 1,
        "entries.formId" : "f548684e-31a7-4e63-af5c-4120670f963f",
        "entries.fieldId" : "element3"
    }, 
    { 
        "$pull" : { 
            "entries.$.value" : { "originalFileName" : "fileB"}
        }
    }
)

语法完全有效,与您编写的内容完全相同,但当然不会在更新语句中为您想要的结果选择正确的元素。

所以$elemMatch使确定这些条件的全部出现在数组中的同一元素上。这就是你想要的,因为它执行个人"查询"在数组的每个元素上,以确保这些条件匹配。