MongoDB 聚合管道的输出结果到集合($out)及合并结果到集合($merge)
上一篇文章,我们介绍了使用聚合管道完成文档之间的关联查询、以及如果将两个管道中的文档进行合并,如果需要进一步了解可以参考:
MongoDB 聚合管道的文档关联查询($lookup)及管道合并($unionWith)https://blog.csdn.net/m1729339749/article/details/130076038同样,之前的几篇文章,我们对聚合管道中的管道参数也进行了详细介绍,主要包括了:
$match:文档过滤
$group:文档分组,并介绍了分组中的常用操作:$addToSet,$avg,$sum,$min,$max等。
$addFields:添加字段,等效于$set
$unset:移除字段
$project:字段投影
$sort:文档排序
$skip:跳过N条文档
$limit:获取N条文档
$sample:随机抽取N条文档
$unwind:分解文档
如果需要进一步了解可以参考:
MongoDB 聚合管道的文档筛选($match)及分组统计($group)https://blog.csdn.net/m1729339749/article/details/130034658MongoDB 聚合管道的字段投影($addFields,$set,$unset,$project)https://blog.csdn.net/m1729339749/article/details/130055110MongoDB 聚合管道的文档操作($sort,$skip,$limit,$sample,$unwind)https://blog.csdn.net/m1729339749/article/details/130066663本篇我们介绍聚合查询的结果输出与合并到集合中:
一、准备工作
初始化零食数据
db.snacks.insertMany([
{ "_id": 1, name: "薯片" },
{ "_id": 2, name: "牛肉干" },
{ "_id": 3, name: "可口可乐" },
{ "_id": 4, name: "旺仔牛奶" }
])
初始化人员数据
db.persons.insertMany([
{ "_id": 3, name: "张三" },
{ "_id": 4, name: "李四" },
{ "_id": 5, name: "王五" },
{ "_id": 6, name: "赵六" }
])
二、输出结果到集合($out)
语法1:{ $out: { db: "<output-db>", coll: "<output-collection>" } }
输出结果到指定库的集合
db: "<output-db>":代表的是要输出到的数据库
coll: "<output-collection>":代表的是要输出到的集合
语法2: { $out: "<output-collection>" }
输出结果到当前库的集合
coll: "<output-collection>":代表的是要输出到的集合
例子:输出零食到test数据库的data集合
db.snacks.aggregate([
{
$out: { db: "test", coll: "data" }
}
])
执行完聚合操作之后,查询test库中的data集合:
{ "_id" : 1, "name" : "薯片" }
{ "_id" : 2, "name" : "牛肉干" }
{ "_id" : 3, "name" : "可口可乐" }
{ "_id" : 4, "name" : "旺仔牛奶" }
发现聚合查询的结果输出到了新的集合中;
例子:输出人员到test数据库的data集合
db.persons.aggregate([
{
$out: { db: "test", coll: "data" }
}
])
执行完聚合操作之后,查询test库中的data集合:
{ "_id" : 3, "name" : "张三" }
{ "_id" : 4, "name" : "李四" }
{ "_id" : 5, "name" : "王五" }
{ "_id" : 6, "name" : "赵六" }
发现聚合查询的结果输出到集合之后,原有的数据被清空。
1、$out 输出结果到集合中时,如果数据库或者集合不存在则会新建
2、$out 输出结果到集合中时,会把原有集合中的数据清空
例子:输出人员到当前数据库的data集合
db.persons.aggregate([
{
$out: "data"
}
])
执行完聚合操作之后,查询当前库中的data集合:
{ "_id" : 3, "name" : "张三" }
{ "_id" : 4, "name" : "李四" }
{ "_id" : 5, "name" : "王五" }
{ "_id" : 6, "name" : "赵六" }
需要注意的是,$out 只能在4.4及以后的版本中使用
三、合并结果到集合($merge)
语法:
{ $merge: {
into: <collection> -or- { db: <db>, coll: <collection> },
on: <identifier field> -or- [ <identifier field1>, ...], // Optional
let: <variables>, // Optional
whenMatched: <replace|keepExisting|merge|fail|pipeline>, // Optional
whenNotMatched: <insert|discard|fail> // Optional
} }
其中,
into:代表的是要合并到的集合;可以是当前库中的集合,也可以指定库中的集合
on:可选,代表的是合并时根据哪些字段数据判断数据是否存在;默认使用_id作为判断数据是否存在的字段
let:可选,用于定义变量
whenMatched: 可选,代表的是如果合并时数据已存在如何处理,默认使用的是replace替换的方式
whenNotMatched:可选,代表的时如果合并时数据不存在如何处理,默认使用的是insert插入的方式
例子:合并零食到当前库中的data集合,并合并人员到当前库中的data集合
db.snacks.aggregate([
{
$merge: {
into: "data"
}
}
])
执行后,查询data集合中的数据:
{ "_id" : 1, "name" : "薯片" }
{ "_id" : 2, "name" : "牛肉干" }
{ "_id" : 3, "name" : "可口可乐" }
{ "_id" : 4, "name" : "旺仔牛奶" }
再合并人员到当前库中的data集合
db.persons.aggregate([
{
$merge: {
into: "data"
}
}
])
执行后,查询data集合中的数据:
{ "_id" : 1, "name" : "薯片" }
{ "_id" : 2, "name" : "牛肉干" }
{ "_id" : 3, "name" : "张三" }
{ "_id" : 4, "name" : "李四" }
{ "_id" : 5, "name" : "王五" }
{ "_id" : 6, "name" : "赵六" }
根据结果可以看出编号3、4的name发生了变化,说明数据存在时使用的是替换的方式;编号5、6是新合并进的数据,说明数据不存在时使用的是插入的方式。
1、$merge 合并结果到集合中时,如果数据库或者集合不存在则会新建
2、$merge 合并结果到集合中时,根据配置的whenMatched对已存在的数据进行操作,根据配置的whenNotMatched对不存在的数据进行操作