我有一个像这样的集合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"
的项目未被删除
我的查询有什么问题?怎么做?
答案 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
使确定这些条件的全部出现在数组中的同一元素上。这就是你想要的,因为它执行个人"查询"在数组的每个元素上,以确保这些条件匹配。