$pull
$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>
应用到每个数组元素,就像它是集合中的一个文档一样。有关示例,请参阅 使用 bulkWrite()
删除所有匹配指定 $pull
条件的项。
如果指定的要删除的 <value>
是一个数组,$pull
只删除与指定 <value>
完全匹配的数组中的元素,包括顺序。
如果指定的要删除的 <value>
是一个文档,$pull
只删除具有完全相同的字段和值的数组中的元素。字段的顺序可以不同。
从MongoDB 5.0开始,mongod
在使用类似于 $pull
的更新操作符且操作数为空表达式({ }
)时不再引发错误。空更新不会产生任何变化,也不会创建任何 操作日志条目(意味着该操作是无效的)。
示例
删除所有等于指定值的项
创建 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"
和"oranges"
从fruits
数组"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 ] } )
以下操作将从 votes
数组中移除所有大于或等于( $gte
)6
的项。
db.profiles.updateOne( { _id: 1 }, { $pull: { votes: { $gte: 6 } } } )
更新操作后,文档中只包含小于 6 的值。
{ _id: 1, votes: [ 3, 5 ] }
使用 bulkWrite()
执行指定的 $pull
条件以移除所有项
以下 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); }
注意
bulkWrite()
db.collection.bulkWrite()
方法在数组中执行多个写入操作。在这个例子中,db.collection.bulkWrite()
在 profiles
集合上执行多个操作。
在 db.collection.bulkWrite()
操作之后,您可以使用以下操作确认文档只包含小于 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
数组中删除所有包含字段 score
等于 8
和字段 item
等于 "B"
的元素
db.survey.updateMany( { }, { $pull: { results: { score: 8 , item: "B" } } } )
$pull
表达式将条件应用于 results
数组的每个元素,就像它是一个顶级文档。
操作完成后,results
数组不包含同时包含字段 score
等于 8
和字段 item
等于 "B"
的文档。
{ _id: 1, results: [ { item: 'A', score: 5 } ] }, { _id: 2, results: [ { item: 'C', score: 8 }, { item: 'B', score: 4 } ] }
$pull
操作符将每个元素视为顶级对象。查询应用于每个元素。表达式不需要使用 $elemMatch
来指定匹配条件。
相反,以下操作不会从原始集合中删除任何元素
db.survey.updateMany( { }, { $pull: { results: { $elemMatch: { score: 8 , item: "B" } } } } )
注意
使用以下命令删除 survey
集合
然后重新创建它 来运行此示例。
从嵌套数组中删除文档
创建一个包含嵌套数组中嵌入的文档的新 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 } ] } ] } ] )
然后您可以使用 $elemMatch
在 answers
数组的元素上指定多个条件:
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 } ] } ] }