使用 MongoDB > v3.6,您可以使用 "all positional operator" $[] 来实现:
db.collection.update({}, { $pull: { "Tests.$[].Data": { "Fact": "1" } } })
更新回应您的评论:
如果您想从Tests 数组中的第一个匹配条目中提取所有匹配实例,则可以这样做:
db.collection.update({"Tests.Data": { $elemMatch: { "Fact": "1" } } }, { $pull: { "Tests.$.Data": { "Fact": "1" } } })
我们来看下面的示例文档:
{
"Tests" : [
{
"Name" : "A",
"Data" : [
{ 'Fact': '1' }, // first matching entry in "A"
{ 'Fact': '1' }, // second matching entry in "A"
{ 'Fact': '2' },
]
},
{
"Name" : "B",
"Data" : [
{ 'Fact': '1' }, // first matching entry in "B"
{ 'Fact': '1' }, // second matching entry in "B"
{ 'Fact': '2' },
]
}
]
}
运行上面的查询一次会给你这个:
{
"Tests" : [
{
"Name" : "A",
"Data" : [
// all matching items gone from "A"
{ 'Fact': '2' }
]
},
{
"Name" : "B",
"Data" : [
{ 'Fact': '1' }, // first matching entry in "B"
{ 'Fact': '1' }, // second matching entry in "B"
{ 'Fact': '2' }
]
}
]
}
再次运行此命令也会清除 "B" 中的所有实例。
{
"Tests" : [
{
"Name" : "A",
"Data" : [
// all matching items gone from "A"
{ 'Fact': '2' }
]
},
{
"Name" : "B",
"Data" : [
// all matching items gone from "B"
{ 'Fact': '2' }
]
}
]
}
但是,如果您只想更新Tests 数组中第一个匹配条目内的第一个匹配实例,那么我认为这不能在单个操作中完成。但是,这里有一个似乎可行的 hack:
db.collection.update({"Tests.Data": { $elemMatch: { "Fact": "1" } } }, { $set: { "Tests.$.Data.0": { "delete_me": 1 } } }) // this will set the first found { Fact: "1" } document inside the Tests.Data arrays to { delete_me: 1 }
db.collection.update({}, { $pull: { "Tests.$[].Data": { "delete_me": 1 } } }) // this will just delete the marked records from all arrays
运行此查询一次将产生以下结果:
{
"Tests" : [
{
"Name" : "A",
"Data" : [
// first matching item gone from "A"
{ 'Fact': '1' }, // second matching entry in "A"
{ 'Fact': '2' }
]
},
{
"Name" : "B",
"Data" : [
{ 'Fact': '1' }, // first matching entry in Name "B"
{ 'Fact': '1' }, // second matching entry in Name "B"
{ 'Fact': '2' }
]
}
]
}
下次你再次运行时,另一个条目将被删除:
{
"Tests" : [
{
"Name" : "A",
"Data" : [
// all matching items gone from "A"
{ 'Fact': '2' }
]
},
{
"Name" : "B",
"Data" : [
{ 'Fact': '1' }, // first matching entry in Name "B"
{ 'Fact': '1' }, // second matching entry in Name "B"
{ 'Fact': '2' }
]
}
]
}
第三轮:
{
"Tests" : [
{
"Name" : "A",
"Data" : [
// all matching items gone from "A"
{ 'Fact': '2' }
]
},
{
"Name" : "B",
"Data" : [
// first matching item gone from "B"
{ 'Fact': '1' }, // second matching entry in Name "B"
{ 'Fact': '2' }
]
}
]
}
最后,第四次运行:
{
"Tests" : [
{
"Name" : "A",
"Data" : [
// all matching items gone from "A"
{ 'Fact': '2' }
]
},
{
"Name" : "B",
"Data" : [
// all matching items gone from "B"
{ 'Fact': '2' }
]
}
]
}