Mongodb在UPDATE操作中使用$pull操作

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第68篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关注威赞。谢谢。

本文基于Mongodb的官方文档,介绍使用$pull, 按照指定条件删除数组中的元素。

定义

在UPDATE中使用$pull操作符,删除数组中的指定元素或删除符合条件的数组元素。

语法

在UPDATE操作中使用$pull操作符时,按照下面的语法。

{$pull: {<field1>: <value|condition>, <field2>: <value|condition>, ...}}

删除嵌入文档或数组当中的数组元素时,需要使用点操作符。

行为

  • 自mongodb5.0开始,UPDATE操作按照字段名称的字典顺序更新字段。当字段中包含数字时,按照数字顺序依次更新字段。当然,对一个文档的多个字段操作,是原子性的。
  • 当在嵌入文档数组类型的数组指定一个删除条件时,$pull操作符的删除条件类似于集合中的文档查询条件一样查询出数组中的每一个文档元素。
  • 当指定删除的值是数组时,指定的数组必须严格等于删除字段中数组元素,包括数组元素的顺序。
  • 当指定删除的值是文档时,要求文档中的字段和即将删除元素文档中的字段和值相同,字段顺序可以不一致。
  • mongodb 5.0版本以后,向$pull传入空表达式({ })时,mongodb不再抛出错误。空表达式不会修改字段值 ,也不会在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"]
    }
    ])

构建数据更新语句,删除fruits数组中的元素"apples", "oranges",删除vegetables数组中的元素"carrots"

db.stores.updateMany({},{$pull:{fruits:{$in: ["apples", "oranges"]}, vegetables: "carrots"}})

查询数据更新后的结果

删除数组中符合查询条件的元素

创建集合profile,其中votes是数组类型字段

db.profile.insertOne({_id: 1, votes:[3,5,6,7,7,8]})

构建数据更新语句,删除votes字段中大于等于6的数据。

db.profile.updateOne({_id: 1}, {$pull: {votes: {$gte:  6}}})

查询操作结果

使用bulkWrite()方法完成数组元素删除操作

构建一个bulkWrite操作过程,完成下面几个步骤

  1. 向集合中插入数据,其中字段votes是数组字段

  2. 更新插入的数据,删除大于等于6的元素

  3. 更新插入的数据,删除小于等于3的元素

    try{
    db.profileBulkWrite.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 (error){
    print(error)
    }

查询bulkWrite()操作结果

db.profileBulkWrite.find()

删除数组中的文档

创建survey并插入数据,其中results字段是文档数组类型

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"}}})

删除嵌套数组中的文档

创建survey文档并插入数据

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}]}
    ]}
])

构建数据更新语句,将包含q的值为2, a的值大于等于8的文档从results数组中删除

db.survey.updateMany({},{ $pull: { "results": {
    answers: {
        $elemMatch: {
            q: 2,
            a: { $gte: 8 }
        }
    }
} } })
相关推荐
XiaoLeisj4 分钟前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
Jasmine_llq23 分钟前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹34 分钟前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
Lenyiin1 小时前
01.02、判定是否互为字符重排
算法·leetcode
鸽鸽程序猿1 小时前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd1 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
Watermelo6171 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
乐之者v1 小时前
leetCode43.字符串相乘
java·数据结构·算法
A懿轩A2 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组