MongoDB聚合小tips
创始人
2024-03-27 22:37:22
0

MongoDB对于嵌套(Embedded)数组的过滤

首先定义下结构

{"play_id": "639045efae627e2aacf35dce","region_id": 1106,"point_list": [{"id": "1faf5aa9-e262-45fe-96dd-64395c96cf5c","name": "获取k8s node证书","status": 0,},{"id": "bc1b11cf-c05a-4964-8ac6-cce1cc23e913“,"name": "获取redis服务器的证书","status": 1,},]
}
{"play_id": "639045efae627e2aacf35dce","region_id": 1107,"point_list": [{"id": "7ac89b59-9657-48bf-8445-171c3de68d53","name": "获取k8s node证书","status": 0,},{"id": "4db7c39d-d2b4-48c2-912d-fca3864ed556","name": "获取redis服务器的证书","status": 3,},{"id": "cd825402-93de-4fb3-876a-e4d2e5d0973b","name": "检查系统最近 15 分钟平均负载小于CPU核数","status": 1,},]
}

这里将业务中的数据结构抽象一部分出来,供作数据使用;

  • play_id: 任务的id
  • region_id:地域id
  • point_list: 执行内容的列表
    –id:执行内容的唯一标识id
    –name:执行内容的名称
    –status:执行内容的状态

现在的小需求是查询某一任务中不同状态执行内容的数量以及列表,这里要注意某一任务会包含多地域的情况

这里主要用到的是Aggregation(官方传送门)

涉及到多步操作且需要有序执行,则使用bson.A来规范过滤条件

	filter := bson.A{}

小tips:多步操作时将每一步的过滤条件应用为bson.D,最后使用bson.A进行有序表示

  • D:BSON 文档(切片)的有序表示
  • A:BSON 数组的有序表示

第一步 查询指定任务

因为本次需求要使用聚合操作,所以在编写filter的时候要记得添加相关语法

	filter1 := bson.D{{"$match", bson.D{{"play_id", playId}}}}

这里可以使用MongoDB Compass来进行作弊:
在这里插入图片描述

第二步 将嵌套数组拆分

使用 $unwind 操作符(传送门)
如果文档中包含 array 类型字段、并且其中包含多个元素,使用 $unwind 操作符会根据元素数量输出多个文档,每个文档的 array 字段中仅包含 array 中的单个元素。

$unwind 操作符返回了多条文档数据,并且改变了字段的类型。

	filter2 := bson.D{{"$unwind",bson.D{{"path", "$point_list"},{"includeArrayIndex", "num"},},},}

path 是决定将哪个嵌套数组进行打平。 以一开始举例的数据为例,则1106这个地域的数据会被分成两条数据,其中每一条数据的“point_list“会变成Object类型
includeArrayIndex则是新数据的名称(数字自增)

第三步 按照name进行聚合|统计数量

使用$group操作法(传送门)

	filter3 := bson.D{{"$group",bson.D{{"_id", "$point_list.name"},{"point_list", bson.D{{"$push", "$point_list"}}},},},})

在这里插入图片描述
_id 是分组的id
point_array 是name=分组id的列表
—————————————————————————————————————————

	filter3 := bson.D{{"$group",bson.D{{"_id", "$point_list.status"},count: {"$sum": 1,}},},})

在这里插入图片描述

将上述分步的filter拼接起来便是最终的过滤条件,又或是写在一起:

filter := bson.A{bson.D{{"$match", bson.D{{"play_id", playId}}}},bson.D{{"$unwind",bson.D{{"path", "$point_list"},{"includeArrayIndex", "num"},},},},}filter = append(filter, bson.D{{"$group",bson.D{{"_id", "$point_list.name"},{"point_array", bson.D{{"$push", "$point_list"}}},},},})

如若需要添加其他匹配条件,append即可(要按照顺序添加

使用pipeline的话代码如下:

[{$match: {play_id: '639045efae627e2aacf35dce'}
}, {$unwind: {path: '$point_list',includeArrayIndex: 'num'}
}, {$group: {_id: '$point_list.status',count: {$sum: 1}}
}]

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...