整理mongodb文档:聚合管道

news2025/1/11 20:49:22

个人博客

整理mongodb文档:聚合管道

个人博客,求关注,电脑版看体验更加,如果不够清晰,请指出来,谢谢

文章概叙

文章主要通过几个常用的聚合表达式来介绍聚合管道的使用,以及从索引的角度来介绍聚合管道的限制,让大家对聚合管道有一个理解。

聚合管道

聚合操作处理数据记录和 return 计算结果。聚合操作将来自多个文档的值组合在一起,并且可以对分组数据执行各种操作以返回单个结果。
如果说,索引能帮我们解决查得慢的问题,那么聚合就能帮我们解决查得复杂的问题。使用聚合管道,就是为了解决复杂的sql的问题,尤其是涉及到多个表的、复杂的查询。

聚合表达式

聚合表达式是我们整个聚合管道学习的核心,其中使用的aggregate方法,就是我们用来做聚合操作的工具。

aggregate的使用方式如下:

db.test.aggregate()

接下来举一个博客网站留评论的例子,给大家讲解下几个常用的表达式,看完例子,对于aggragate也能熟悉。

假设有如下两张表,article表示文章,comment表示评论。
在article表中,存储着代表一篇博客的信息,内容如下:

在这里插入图片描述

在代表文章的article表中,我们用"article_id"作为文章的唯一标识,不使用默认的"_id"。其中的"can_comment"字段表示该博客是否允许评论。
现在的业务逻辑如下:当我们后台接收到前端的新增评论的请求时,我们需要在comment表中新增一条评论。

正常的情况下,我们会去用find方法去article表中查询是否有满足可以评论的数据,再用insertOne去comment表中新增一条记录,整体看下来至少需要两个sql。但使用聚合管道则只需要一个sql就可以做到同样的事情。所以遇到相似的业务的时候,基本都会选择使用aggregate来完成我们的业务。

接下来,使用aggregate来实现我们上述两步的逻辑。

使用"$match"从article表中查看是否有符合条件的记录。

过滤文档流以仅允许匹配的文档未经修改地传递到下一个管道阶段。 $match使用标准的 MongoDB
查询。对于每个输入文档,输出一个文档(匹配)或零文档(不匹配)。

db
    .article
    .aggregate([
        {
            "$match": {
                "can_comment": true,
                "article_id":'1'
            }
        }
    ])

返回结果如下,筛选出了我们选中的记录
在这里插入图片描述

2.在第一步中我们得到了一个数组对象,但是我们只需要一个文章的id,此时可以使用"$project"对字段进行保留跟丢弃,下方的例子,就直接保留article_id以及删除

重新整形流中的每个文档,例如添加新字段或删除现有字段。对于每个输入文档,输出一个文档。 有关删除现有字段,请参见$unset。

db
    .article
    .aggregate([
        {
            "$match": {
                "can_comment": true,
                "article_id": '1'
            }
        },
        {
            "$project": {
                "article_id": 1,
                "_id": 0
            }
        }
    ])

在这里插入图片描述

​3.我们需要将整理出来的数据放到comment表中,但是我们需要用"$addFields"来增加评论内容的字段

向文档添加新字段。类似于 p r o j e c t , project, projectaddFields重塑了流中的每个文档;具体而言,通过向输出文档添加新字段,该文档包含输入文档和新添加字段中的现有字段。
s e t 是 set是 setaddFields的别名。

添加了comment之后的sql如下:

db
    .article
    .aggregate([
        {
            "$match": {
                "can_comment": true,
                "article_id": '1'
            }
        },
        {
            "$project": {
                "article_id": 1,
                "_id": 0
            }
        },
        {
            "$set": {
                "comment": "文章的评论",
                "commentator": 'mk',
                "comment_time":"2023-08-22 18:00:00"
            }
        }])

在这里插入图片描述

此时,数据整理完毕,我们需要用到"$merge"方法将其写入到comment表中了

将聚合管道的结果文档写入集合。这个阶段可以将结果合并到一个输出集合中(插入新文档、合并文档、替换文档、保留现有文档、操作失败、使用自定义更新管道处理文档)。要使用$merge阶段,它必须是管道中的最后一个阶段。version 4.2 中的新功能

db
    .article
    .aggregate([
        {
            "$match": {
                "can_comment": true,
                "article_id": '1'
            }
        },
        {
            "$project": {
                "article_id": 1,
                "_id": 0
            }
        },
        {
            "$set": {
                "comment": "文章的评论",
                "commentator": 'mk',
                "comment_time": "2023-08-22 18:00:00"
            }
        }, {
            "$merge": {
                "into": 'comment'
            }
        }])

添加链接描述

当然,上述的代码是建立在自己article表中有该条数据的情况下,接下来贴一张在article表中查询没有数据时候的运行结果​

在这里插入图片描述

可以看到,由于在article表中查不到数据,所以后续的操作都被取消​了。

聚合管道限制

聚合管道能满足我们许多复杂的需求,能让我们在db层就将我们的数据整理好,而不是通过一个又一个find方法去查询索引能帮我们快速的查询。而聚合能帮我们做复杂的数据。因此我们需要处理好索引跟聚合管道的关系,防止顾此失彼。

举一个例子,在一个集合中,使用"$facet"起一个别名作为数据

在同一组输入文档的单个阶段内处理多个聚合管道。允许创建能够在单个阶段中跨多个维度或方面描述数据的多面聚合。

db
    .article
    .aggregate([
        {
            "$facet": {
                "article_list": [{
                    "$match": {
                        "can_comment": true
                    }
                }]}
        }])

该例子直接去article表中查询能够评论的文章,然后将其赋名为article_list。​结果如下:

在这里插入图片描述

此时,我们使用explain查看查询的​状态,看看是否使用到了索引。

db
    .article
    .aggregate([
        {
            "$facet": {
                "article_list": [{
                    "$match": {
                        "can_comment": true
                    }
                }]}
        }]).explain("executionStats")

在这里插入图片描述

但是如果直接使用"$match"呢?

db
    .article
    .aggregate([{
        "$match": {
            "can_comment": true
        }
    }
    ]).explain()

在这里插入图片描述

可以看到,当我们使用"$facet"在最外围的时候,是不使用index查询的,就会导致很慢,而我们直接使用"$match"的时候,使用索引就会让查询时间大大的优化。
其他例子还有很多,这儿只是举个例子,如果出现了查询缓慢的情况,我建议使用explain看下运行结果。​

allowDiskUse

必须要提一嘴的是关于16mb的内存,前面提及到了aggregate会将数据整理完返回给我们的后台,但是很多时候会报错,显示内存超过16MB,这是可以设置allowDiskUse为true。当前的代码是在shell中使用,​建议大家自己去官网下查看。​

单用途聚合操作

单用途聚合操作顾名思义,指的是用途单一的聚合管道,主要包括下面三种计数的方法,但是了解了之后会发现基本都是用来统计数量的,现在列举如下

1.estimatedDocumentCount

统计文档总数,返回集合或视图中所有文档的计数。该方法包装count命令。

db.test.estimatedDocumentCount()

2.count
也是一种计数的方式,但是可以添加条件,使用方法如下

db.test.count()
db.test.count({string:'a'})

3.distinct

查询不同值,并返回一个数组,包含所有的结果

db.test.distinct('string')

在这里插入图片描述

最后的话

本文章不会详细介绍每一个表达式的优缺点,只会告诉大家要注意的点,最常用的表达式会后面再写​。毕竟框架搭建好了,添砖加瓦的事情可以慢慢来,aggregate的难度不大,就跟积木一样,不断的组装,完成我们的需求​

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

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

相关文章

使用lambda表达式提取共用代码使其更加简洁

1、在开发预下单接口访问并发问题出现需要加锁代码如下 RLock lock redissonClient.getLock(String.format(appointmentKey, activityId, studentId));try {boolean tryLock lock.tryLock(10, 20, TimeUnit.SECONDS);if (tryLock) {AppointmentMallOrderInfoDTO appointmentM…

【修改MAC地址工具】-TMAC

本文介绍修改MAC地址的神器小工具Technitium-MAC-Address-Changer 1. 下载地址 地址1: https://technitium.com/tmac/ 地址2: 链接:https://pan.baidu.com/s/1-jtwQ936gtepVWXKo_qwfg 提取码:2n1s 2. 安装 直接双击就可以安装…

iTwinCapture中文版原ContextCapture安装包以及安装教程

iTwinCapture软件安装教程 一、获取软件 中文安装包评论区或后台回复iTwinCapture 在App Store或Google Play搜索软件名称"iTwin Capture",下载安装软件。 您也可以在Bentley官网下载对应的iTwin Capture版本。 二、软件安装 点击下载后的安装包,根据提示完成安装…

NR SDAP

在NR系统的核心网中,业务不再以EPS承载的形式下发到接入网,而是以QoS flow的形式下发到接入网。在核心网引入QoS flow之后,可以提供比EPS承载更好的QoS粒度,从而更好地对IP数据流进行管理。一个QoS flow由一个或多干IP data stream聚合而成。因此,在核心网中,IP flow映射…

git 统计(命令)

查询某人某个时刻提交了多少代码 added 添加代码 removed 删除代码 total 总代码 git log --author刘俊秦 --since2023-08-01 00:00:00 --until2023-08-23 23:00:00 --prettytformat: --numstat | awk { add $1; subs $2; loc $1 - $2 } END { printf "added lines: %s…

JW0818近电报警芯片

JW0818 市电感应报警电路适用于电业人员和电信行业施工人员的安全保护用品–近电预警器 报警电路。 特别注意芯片引脚6,输出信号是方波,而不是高低电平;在产品开发过程遇到这个坑。

C++中的抽象类和接口

面向对象中的抽象概念 在进行面向对象分析时,会发现一些抽象的概念! 图形的面积如何计算? 什么是抽象类? 在现实中需要知道具体的图像类型才能求面积,所以对概念上的 "图形" 求面积是没有意义的&#xff…

私有化部署即时通讯平台,30分钟替换钉钉和企业微信

随着企业对即时通讯和协作工具的需求不断增长,私有化部署的即时通讯平台成为企业的首选。WorkPlus作为有10余年行业深耕经验与技术沉淀品牌,以其安全高效的私有化部署即时通讯解决方案,帮助企业在30分钟内替换钉钉和企业微信。本文将深入探讨…

基于Jenkins自动打包并部署docker、PHP环境,ansible部署-------从小白到大神之路之学习运维第86天

第四阶段提升 时 间:2023年8月23日 参加人:全班人员 内 容: 基于Jenkins部署docker、PHP环境 目录 一、环境部署 (一)实验环境,服务器设置 (二)所有主机关闭防火墙和selinu…

Docker容器与虚拟化技术:Gitlab账户注册

目录 一、实验 1.gitlab 一、实验 1.gitlab (1) 概念 GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务。 (2)官网 The DevSecOps Platform | GitLab (3&#…

nginx 一个端口配置前后端分离项目访问

nginx 一个端口配置前后端分离项目访问 nginx配置 server {listen 8888;server_name _;location ~ .*\.(gif|jpg|jpeg|png|pdf|txt|zip|rar|7z|doc|docx|xls|xlsx|ppt|pptx|mp3|mp4)$ {root D:/platform/tomcat/apache-tomcat-9.0.31/webapps/resources;}location /api/…

智慧灌区闸控一体化解决方案

智慧灌区闸控一体化解决方案是指将灌溉系统中的闸门控制与水文监测、远程通信和数据管理等功能相集成,实现对灌区水资源的智能化管理和控制的方案。以下是智慧灌区闸控一体化解决方案的主要组成部分: ■闸门控制系统:包括闸门、闸门执行器和控…

计算机视觉入门 4)滑动窗口

系列文章目录 计算机视觉入门 1)卷积分类器计算机视觉入门 2)卷积和ReLU计算机视觉入门 3)最大池化计算机视觉入门 4)滑动窗口计算机视觉入门 5)自定义卷积网络计算机视觉入门 6) 数据集增强(D…

WoShop跨境电商系统开发:打造全球畅销产品

随着全球贸易的发展,跨境电商成为了许多企业拓展市场、增加盈利的重要途径。而要在跨境电商领域取得成功,开发一个高效、稳定的跨境电商系统是至关重要的。本文将为您详细介绍跨境电商系统开发,以及打造全球畅销产品的关键要素和方法。 一、…

H5页面跳转到公众号关注页面

效果展示: 未关注展示关注;已关注展示发消息 实现步骤: 登录微信公众平台 : https://mp.weixin.qq.com/鼠标右键选择查看网页源代码,找到uin_base64值如果没有uin_base64,那就找到uin进行base64编码编码地…

在使用springer模板的时候,引用书 book时候,末尾的引文地方出现问号???

文章目录 背景解决办法 背景 其实springer有很多模板的,比如nature系列有一个模板,计算机系列有一个模板,计算机系列的模板引用参考文献时好像不会出现标题的问题,我是使用nature系列模板出现这个问题的,如下&#xf…

Linux网络服务 七:iptables防火墙工具

文章目录 1.防火墙简介1.1 什么是防火墙1.2 Netfilter1.3 firewalld和iptables 2. iptables工具简述2.1 iptables的定义2.2 三种报文流向2.3iptables的表和链2.3.1**四表** ----规则表2.3.2**五链** ----规则链 3.iptables配置及操做3.1 基本语法3.1.1 控制类型项 (要大写!!!)3…

AR地图微信小程序:数字化时代下地图应用的新突破

随着数字化时代的到来,地图应用成为人们日常生活中不可或缺的工具。而随着增强现实(AR)技术的快速发展,AR地图微信小程序应运而生,为用户提供了一种全新的地图导航体验。本文将深入探讨AR地图微信小程序的专业性和思考…

LoRA继任者ReLoRA登场,通过叠加多个低秩更新矩阵实现更高效大模型训练效果

论文链接: https://arxiv.org/abs/2307.05695 代码仓库: https://github.com/guitaricet/peft_pretraining 一段时间以来,大模型(LLMs)社区的研究人员开始关注于如何降低训练、微调和推理LLMs所需要的庞大算力&#xf…

【洁洁送书第五期】为什么我们要了解可观测性工程

导读 可观测性已成为一个热门话题,并广受关注。随着它的普及,“可观测性”不幸被误作“监控”或“系统遥测”的同义词。可观测性是软件系统的一个特征。而且,只有当团队采用新的实践进行持续开发时,才能在生产软件系统中有效利用这…