7

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

 2 years ago
source link: https://wiki.eryajf.net/pages/f85bb3/#%E6%B7%BB%E5%8A%A0%E5%A4%9A%E6%9D%A1%E6%95%B0%E6%8D%AE
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

# 前言结论

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

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

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

5c9f3183898546f5.jpg

# 实验验证

# 准备数据

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

$ 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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK