定义
$pull$pull操作符会从现有大量中删除与指定条件匹配的一个或多个值的所有实例。
兼容性
可以使用 $pull 查找托管在以下环境中的部署:
- MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
$pull操作符具有以下形式:
{ $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } }
要在嵌入式文档或数组中指定 <field>,请使用点符号。
行为
从 MongoDB 5.0 开始,更新操作符按字典顺序处理具有基于字符串的名称的文档字段。具有数字名称的字段按数字顺序处理。详情请参阅更新操作符行为。
如果指定<condition> 并且大量元素是嵌入式文档,则$pull 操作符将应用<condition> ,将每个大量元素视为集合中的文档。有关示例,请参阅从文档数组中删除项目。
如果要删除的指定<value> 是大量,则$pull 仅删除大量中与指定的<value> 完全匹配的元素,包括顺序。
如果要删除的指定<value> 是文档,则$pull 仅删除大量中具有完全相同字段和值的元素。字段的顺序可以不同。
从MongoDB5.0 开始,当您将 等更新操作符符与空操作数表达式()mongod $pull一起使用时,{ } 不再引发错误。空更新不会导致任何更改,也不会创建oplog条目(意味着该操作为“不操作”)。
示例
删除所有等于指定值的项
创建 stores 集合:
db.stores.insertMany( [ { _id: 1, fruits: [ "apples", "pears", "oranges", "grapes", "bananas" ], vegetables: [ "carrots", "celery", "squash", "carrots" ] }, { _id: 2, fruits: [ "plums", "kiwis", "oranges", "bananas", "apples" ], vegetables: [ "broccoli", "zucchini", "carrots", "onions" ] } ] )
以下操作会删除
"apples"和fruits数组中的"oranges""carrots"vegetables数组中的
db.stores.updateMany( { }, { $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } } )
使用 db.collection.find() 确认结果:
{ _id: 1, fruits: [ 'pears', 'grapes', 'bananas' ], vegetables: [ 'celery', 'squash' ] }, { _id: 2, fruits: [ 'plums', 'kiwis', 'bananas' ], vegetables: [ 'broccoli', 'zucchini', 'onions' ] }
删除与指定 $pull 条件匹配的所有项
创建 profiles 集合:
db.profiles.insertOne( { _id: 1, votes: [ 3, 5, 6, 7, 7, 8 ] } )
以下操作将从大于或等于 ($gte) 6 的 votes 数组中删除所有项:
db.profiles.updateOne( { _id: 1 }, { $pull: { votes: { $gte: 6 } } } )
更新操作后,文档中只有小于 6 的值:
{ _id: 1, votes: [ 3, 5 ] }
使用删除项 bulkWrite()
以下 db.collection.bulkWrite() 操作:
try { db.profilesBulkWrite.bulkWrite( [ { insertOne: { "document": { _id: 1, votes: [ 3, 5, 6, 7, 7, 8 ] } } }, { updateOne: { "filter": { _id: 1 }, "update": { $pull: { votes: { $gte: 6 } } } } }, { updateOne: { "filter": { _id: 1 }, "update": { $pull: { votes: { $lte: 3 } } } } } ] ); } catch (e) { print(e); }
操作后,您可以确认文档中的值仅小于 6 并且大于 3:
db.profilesBulkWrite.find()
该操作返回以下内容:
[ { _id: 1, votes: [ 5 ] } ]
从文档数组中删除项
创建 survey 集合:
db.survey.insertMany([ { _id: 1, results: [ { item: "A", score: 5 }, { item: "B", score: 8 } ] }, { _id: 2, results: [ { item: "C", score: 8 }, { item: "B", score: 4 } ] } ] )
以下操作会删除 results 数组中同时包含等于 8 的 score 字段和等于 "B" 的 item 字段的所有元素:
db.survey.updateMany( { }, { $pull: { results: { score: 8 , item: "B" } } } )
$pullresults表达式将条件应用于 大量的每个元素,就好像它是顶级文档一样。
执行此操作后,results 数组中不再有同时包含等于 8 的 score 字段和等于 "B" 的 item 字段的文档。
{ _id: 1, results: [ { item: 'A', score: 5 } ] }, { _id: 2, results: [ { item: 'C', score: 8 }, { item: 'B', score: 4 } ] }
$pull操作符将每个元素视为一个顶级对象。查询会应用于每个元素。该表达式不需要使用$elemMatch 来指定匹配条件。
但是,以下操作不会$pull 原始集合中的任何元素:
db.survey.updateMany( { }, { $pull: { results: { $elemMatch: { score: 8 , item: "B" } } } } )
从嵌套数组中删除文档
使用嵌入在嵌套数组中的文档创建新的 survey 集合。
db.survey.drop() db.survey.insertMany( [ { _id: 1, results: [ { item: "A", score: 5, answers: [ { q: 1, a: 4 }, { q: 2, a: 6 } ] }, { item: "B", score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 9 } ] } ] }, { _id: 2, results: [ { item: "C", score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 7 } ] }, { item: "B", score: 4, answers: [ { q: 1, a: 0 }, { q: 2, a: 8 } ] } ] } ] )
要对 answers 数组的元素指定多个条件,请使用 $elemMatch:
db.survey.updateMany( { }, { $pull: { results: { answers: { $elemMatch: { q: 2, a: { $gte: 8 } } } } } } )
该操作更新了每个匹配文档中的 results 数组。当嵌入式 answers 数组的元素与突出显示行中的选择条件相匹配时,db.collection.updateMany() 从 results 中删除了文档。
{ _id: 1, results: [ { item: 'A', score: 5, answers: [ { q: 1, a: 4 }, { q: 2, a: 6 } ] } ] }, { _id: 2, results: [ { item: 'C', score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 7 } ] } ] }