二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • Shell编程

  • Go编程笔记

    • 开发技巧

      • go日常开发代码片段
      • golang交叉编译
      • 两个切片内容相减的几种方法
      • golang以结构体中某个字段进行排序
      • vscode开发golang报黄提示composite literal uses unkeyed fields
      • golang使用$in或$nin查询MongoDB是否在数组内的数据
      • golang使用$push和$addToSet往数组添加字段的异同
        • 前言结论
        • 实验验证
          • 准备数据
          • 添加单条数据
          • 添加多条数据
      • MongoDB自增ID在golang中的实践
      • golang数据类型转换汇总
      • 记录VSCode中写Go代码切换Sqlite无CGO依赖版本的过程以及遇到的五个问题
      • 企业微信自建应用-golang校验回调
      • 对接腾讯云未集成到SDK的接口开发实践小记
      • Go开发实践之Gin框架将前端的dist目录embed到二进制
    • 库包研究

    • 个人项目

  • 前端编程笔记

  • Go学习笔记

  • Vue-21年学习笔记

  • Vue-22年重学笔记

  • 编程世界
  • Go编程笔记
  • 开发技巧
二丫讲梵
2022-03-11
目录

golang使用$push和$addToSet往数组添加字段的异同

文章发布较早,内容可能过时,阅读注意甄别。

# 前言结论

在面对 MongoDB 的集合字段交互时,我们可能会接触到$push与$addToSet两个方法,两个方法看似功能差不多,实际使用场景中也有一些不同,这里先说结论。

  • 相同
    • 都是提供了往数组添加元素的功能。
  • 差异
    • 无论数组对象是什么样,相同的值,多次添加时,$addToSet会自动去重,而$push不会。
    • 无论数组对象是什么样,$addToSet一次只能添加一个元素,而$push可以结合$each实现一次添加多个元素。

进入验证之前,先放一张美女图提神醒脑一波:

# 实验验证

# 准备数据

首先我们可以看以下一组操作,体现两者都能够添加元素到数组内,准备测试数据如下,后边每次重新测试,都会重置准备的数据,不再赘述。

$ db.datas.insert(
    [
        {"name":"aa"},
        {"name":"bb"},
        {"name":"cc"},
        {"name":"dd"}
    ]
)
1
2
3
4
5
6
7
8

看一眼数据:

$ db.getCollection('datas').find({})
/* 1 */
{
    "_id" : ObjectId("622b04709d75257165271fc5"),
    "name" : "aa"
}

/* 2 */
{
    "_id" : ObjectId("622b04709d75257165271fc6"),
    "name" : "bb"
}

/* 3 */
{
    "_id" : ObjectId("622b04709d75257165271fc7"),
    "name" : "cc"
}

/* 4 */
{
    "_id" : ObjectId("622b04709d75257165271fc8"),
    "name" : "dd"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 添加单条数据

执行如下一波操作添加字段到一个列表:

// 添加单个元素到列表
db.datas.update(
   { "name" : "aa" },
   { $addToSet: { "label_list": "11" } }
)
// 添加单个元素到列表
db.datas.update(
   { "name" : "aa" },
   { $addToSet: { "label_list": "11" } }
)
// 添加一个对象到列表
db.datas.update(
   { "name" : "bb" },
   { $addToSet: { "label_list": {"name":"bb-1","age":"bb-1"} } }
)
// 添加一个对象到列表
db.datas.update(
   { "name" : "bb" },
   { $addToSet: { "label_list": {"name":"bb-1","age":"bb-1"} } }
)

// 添加单个元素到列表
db.datas.update(
   { "name" : "cc" },
   { $push: { "label_list": "22" } }
)
// 添加单个元素到列表
db.datas.update(
   { "name" : "cc" },
   { $push: { "label_list": "22" } }
)
// 添加一个对象到列表
db.datas.update(
   { "name" : "dd" },
   { $push: { "label_list": {"name":"dd-2","age":"dd-2"} } }
)
// 添加一个对象到列表
db.datas.update(
   { "name" : "dd" },
   { $push: { "label_list": {"name":"dd-2","age":"dd-2"} } }
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

注意:如上命令之所以执行两次,是为了结合结果看出其中差异。

此时再次查库可看到结果如下:

$ db.getCollection('datas').find({})
/* 1 */
{
    "_id" : ObjectId("622b08129d75257165271fcd"),
    "name" : "aa",
    "label_list" : [
        "11"
    ]
}

/* 2 */
{
    "_id" : ObjectId("622b08129d75257165271fce"),
    "name" : "bb",
    "label_list" : [
        {
            "name" : "bb-1",
            "age" : "bb-1"
        }
    ]
}

/* 3 */
{
    "_id" : ObjectId("622b08129d75257165271fcf"),
    "name" : "cc",
    "label_list" : [
        "22",
        "22"
    ]
}

/* 4 */
{
    "_id" : ObjectId("622b08129d75257165271fd0"),
    "name" : "dd",
    "label_list" : [
        {
            "name" : "dd-2",
            "age" : "dd-2"
        },
        {
            "name" : "dd-2",
            "age" : "dd-2"
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

可以看到两个指令都支持简单和复杂对象的交互,只不过使用$addToSet添加时,如果列表已存在该值,则不会重复添加。

# 添加多条数据

添加的多个元素为简单字符串:

$ db.datas.update(
   { name: "aa" },
   { $push: { "label_list": { $each: [ "90", "92", "85" ] } } }
)
$ db.datas.update(
   { name: "aa" },
   { $push: { "label_list": { $each: [ "90", "92", "85" ] } } }
)

$ db.datas.update(
   { name: "bb" },
   { $addToSet: { "label_list": { $each: [ "90", "92", "85" ] } } }
)
$ db.datas.update(
   { name: "bb" },
   { $addToSet: { "label_list": { $each: [ "90", "92", "85" ] } } }
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

其中$push多次添加会重复添加:

/* 1 */
{
    "_id" : ObjectId("622b13239d75257165271fdd"),
    "name" : "aa",
    "label_list" : [
        "90",
        "92",
        "85",
        "90",
        "92",
        "85"
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13

再看$addToSet的效果,会自动去重:

/* 2 */
{
    "_id" : ObjectId("622b13239d75257165271fde"),
    "name" : "bb",
    "label_list" : [
        "90",
        "92",
        "85"
    ]
}
1
2
3
4
5
6
7
8
9
10

添加的多个元素为复杂对象:

$ db.datas.update(
   { "name" : "cc" },
   { $push: { "link_model":{
        $each: [{"name":"aa-1","age":"3"},{"name":"bb-1","age":"4"}],
		"$position":0,
     } } }
)
$ db.datas.update(
   { "name" : "cc" },
   { $push: { "link_model":{
        $each: [{"name":"aa-1","age":"3"},{"name":"bb-1","age":"4"}],
		"$position":0,
     } } }
)

$ db.datas.update(
   { "name" : "dd" },
   { $addToSet: { "link_models":{
        $each: [{"name":"aa-1","age":"3"},{"name":"bb-1","age":"4"}],
     } } }
)
$ db.datas.update(
   { "name" : "dd" },
   { $addToSet: { "link_models":{
        $each: [{"name":"aa-1","age":"3"},{"name":"bb-1","age":"4"}],
     } } }
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

然后查看通过$push添加的这条数据,没有自动查重:

/* 3 */
{
    "_id" : ObjectId("622b13239d75257165271fdf"),
    "name" : "cc",
    "link_model" : [
        {
            "name" : "aa-1",
            "age" : "3"
        },
        {
            "name" : "bb-1",
            "age" : "4"
        },
        {
            "name" : "aa-1",
            "age" : "3"
        },
        {
            "name" : "bb-1",
            "age" : "4"
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

再看使用$addToSet,则可以自动去重:

/* 4 */
{
    "_id" : ObjectId("622b13239d75257165271fe0"),
    "name" : "dd",
    "link_models" : [
        {
            "name" : "aa-1",
            "age" : "3"
        },
        {
            "name" : "bb-1",
            "age" : "4"
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
微信 支付宝
#MongoDB
上次更新: 2024/07/04, 22:40:37
golang使用$in或$nin查询MongoDB是否在数组内的数据
MongoDB自增ID在golang中的实践

← golang使用$in或$nin查询MongoDB是否在数组内的数据 MongoDB自增ID在golang中的实践→

最近更新
01
记录二五年五一之短暂回归家庭
05-09
02
学习周刊-总第210期-2025年第19周
05-09
03
学习周刊-总第209期-2025年第18周
05-03
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式