@@ -1,58 +0,0 @@ 07.golang使用$push和$addToSet往数组添加字段的异同 | 凤凰涅槃进阶之路

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

Abel sun2023年1月6日约 944 字大约 3 分钟

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

前言结论

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

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

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

实验验证

准备数据

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

$ db.datas.insert(
    [
        {"name":"aa"},
        {"name":"bb"},
        {"name":"cc"},
        {"name":"dd"}
    ]
)

看一眼数据:

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

添加单条数据

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

// 添加单个元素到列表
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"} } }
)

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

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

$ 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"
        }
    ]
}

可以看到两个指令都支持简单和复杂对象的交互,只不过使用$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" ] } } }
)

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

/* 1 */
{
    "_id" : ObjectId("622b13239d75257165271fdd"),
    "name" : "aa",
    "label_list" : [ 
        "90", 
        "92", 
        "85", 
        "90", 
        "92", 
        "85"
    ]
}

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

/* 2 */
{
    "_id" : ObjectId("622b13239d75257165271fde"),
    "name" : "bb",
    "label_list" : [ 
        "90", 
        "92", 
        "85"
    ]
}

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

$ 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"}],
     } } }
)

然后查看通过$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"
        }
    ]
}

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

/* 4 */
{
    "_id" : ObjectId("622b13239d75257165271fe0"),
    "name" : "dd",
    "link_models" : [ 
        {
            "name" : "aa-1",
            "age" : "3"
        }, 
        {
            "name" : "bb-1",
            "age" : "4"
        }
    ]
}
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.9.1