MongoDB聚合小tips

news2024/11/16 13:22:38

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/73344.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Allegro如何检查过孔是否重叠的四种方法操作指导

Allegro如何检查过孔是否重叠的四种方法操作指导 Allegro可以检查过孔是否重叠,避免重孔的情况的出现,具体检查方法如下 一.非同名网络过孔重叠 以下图为例 打开DRC开关,EnableDRC 打开Constraints-Mode 打开Spacing规则via的规则 可以看到非同名网络过孔,孔重叠在一…

C#多线程之Thread,ThreadPool,Task,Parallel

总目录 文章目录总目录前言一、多线程以及与之相关概念1.基本概念1)进程2)线程3)多线程2.同步、异步1)同步方法2)异步方法二、Thread1.线程的使用1)创建并开启线程2)线程的属性设置&方法调用…

【微电网】具有柔性结构的孤岛直流微电网的分级控制(Malab代码实现)

💥💥💥💞💞💞欢迎来到本博客❤️❤️❤️💥💥💥 📝目前更新:🌟🌟🌟电力系统相关知识,期刊论文&…

carsim/trucksim获取轮胎侧偏刚度、纵向刚度

本文参考:https://blog.csdn.net/weixin_44902384/article/details/107926814 这个方法适应计算侧偏刚度、纵向刚度,因为魔术公式里y 可以代表侧向力、纵向力 针对上面的内容,有两个问题需要解释。1是魔术公式轮胎中 有的是tan-1 有的是ar…

[Linux]------线程池的模拟实现和读者写者锁问题

文章目录前言一、线程池二、线程安全的单例模式什么是单例模式什么是设计模式单例模式的特点三、STL,智能指针和线程安全STL中的容器是否是线程安全的?智能指针是否是线程安全的?四、其他常见的各种锁五、读者写者问题读写锁读写锁接口初始化…

云开发智能家居客户案例详解(内附拓扑图)

万物互联,大至全世界,小至一间房,物联网和云计算技术的高速发展使得住宅变得愈发智能化。 在“互联网”时代,智能家居开始走入千家万户,不断提升着家居生活的安全性、舒适型、便利性和环保性,逐渐变成人们…

Linux 用户权限

用户权限1、访问权限2、chmod 命令3、chown 命令4、chgrp命令5、权限掩码6、lsattr 命令7、chattr命令8、文件的特别权限suid权限set位权限粘滞位权限(Sticky)9、ACL访问控制列表setfacl命令getfacl命令示例10、sudo11、SELinux1、访问权限 shell在创建…

SpringBoot2学习笔记--入门及HelloWorld

SpringBoot2学习笔记--入门及HelloWorld1 系统要求1.1、maven设置2、HelloWorld2.1、创建maven工程2.2、引入依赖2.3、创建主程序2.4、编写业务2.5、测试2.6、简化配置2.7、简化部署1 系统要求 ● Java 8 & 兼容java14 . ● Maven 3.3 ● idea 2019.1.2 1.1、maven设置 …

Java版 剑指offer笔记(一)

1.数组中重复的数字 思路1: 使用哈希表,哈希表是一种根据关键码(key)直接访问值(value)的一种数据结构。而这种直接访问意味着只要知道key就能在O(1)时间内得到value,因此哈希表常用来统计频率…

软件测试有哪些常用的测试方法?

软件测试是软件开发过程中重要组成部分,是用来确认一个程序的质量或者性能是否符合开发之前提出的一些要求。软件测试的目的有两方面,一方面是确认软件的质量,另一方面是提供信息,例如,给开发人员或者程序经理反馈意见…

4.MyBatis映射

需求分析 1.订单商品数据模型 (1).表 用户表user:记录了购买商品的用户信息 订单表orders:记录了用户所创建的订单信息 订单明细表orderdetail:记录了订单的详细信息 商品表item:记录了商品详细信息 (2).表与表之间的业务关系 在分析表与表之间的业务关系时,需要建…

Nginx的反向代理和负载均衡

Nginx: Nginx作为面试中的大…小头目,自然是不能忽视的,而以下两点就是它能成为面试中头目的招牌。 反向代理和负载均衡 在此之前,我们先对Nginx做一个简单的了解 Nginx概述: Nginx (engine x) 是一个高性能的HTTP…

Ansible——inventory 主机清单

Ansible——inventory 主机清单Ansible——inventory 主机清单inventory简介ansible配置文件的优先级ansible命令常用参数主机清单文件hosts(/etc/ansible/hosts)通过列表的方式标识主机范围指定主机端口使用主机名表示主机范围inventory 中的变量主机变…

JS 数组方法 every 和 some 的区别

1. 前言 2. every 和 some 相同点 3. every 和 some 的区别 4. every 和 some 总结 1. 前言 JS 数组方法 every 和 some 的区别 ? 这是某位前端玩家遇到的面试题 特定场景合理的使用 JS 方法,不仅可以减少我们的代码量,还能更轻松的阅读…

宇航服,真正的“科技”与“狠活”!

千百年的探索仰望和摘星的遐想,已照进现实,浩瀚的天宫,我们亦可置身其中。 北京时间2022年12月4日20时09分,神舟十四号载人飞船返回舱在东风着陆场成功着陆,标志着太空出差183天的宇航员正式回家!据悉&…

基于PCA 和迭代 Canny Edge皮肤病变分割算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

NLP_learning 中文基本任务与处理(分词、停用词、词性标注、语句依存分析、关键词抽取、命名实体识别)介绍、jieba工具库

文章目录1、分词2、停用词和N-gram停用词N-gram3、 更多任务(词性标注、依赖分析、NER、关键词抽取)词性标注句法依存分析命名实体识别关键词抽取4、 jieba工具库使用(1)基本分词函数与用法(2)词性标注&…

【LeetCode】C++:数组类算法-双索引技巧-对撞指针

目录 167. 两数之和 II - 输入有序数组 125.验证回文串 345.反转字符串中的元音字母 11.盛最多水的容器 209.长度最小的数组 167. 两数之和 II - 输入有序数组 给你一个下标从1开始的整数数组 numbers ,该数组已按非递减顺序排列 ,请你从数组中找出…

视频剪辑软件哪个好用?快把这些软件收好

现如今自媒体行业正在如火如荼的发展,越来越多的人加入进视频剪辑的队伍中。小伙伴们也有萌生想要剪辑视频的念头吗?大家是否苦于不知道该如何视频剪辑呢?为了帮助大家解决这个问题,今天我就来为大家教几种不错的剪辑方法&#xf…

YOLOv5图像分割中的NMS处理

在上一篇文章YOLOv5图像分割--SegmentationModel类代码详解有讲到图像经过YOLOv5网络后得到的输出形式,主要是调用了BaseModel类下的forward得到的输出,输出的shape为【batch,25200,117】,这里的25200相当于总的anchors数量【以640*640的输入…