07.golang使用$push和$addToSet往数组添加字段的异同
2023年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