MongoDB aggregate 管道聚合查询

文章目录

  • 数据准备
  • 条件查询
  • 聚合查询
    • 模糊查询
    • 拆分数据
    • 关联查询
      • 根据用户组查询用户
      • 根据用户查询用户组
    • 控制显示
    • 字段置顶
    • 合并字段
    • 新增或修改字段
    • 计算总数
    • 分页查询
    • 分页查询加总数
    • 排序
    • 分组

数据准备

UserPO

@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user")
public class UserPO extends BasePO {private String name;private String description;}

UserGroupPO

@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user_group")
public class UserGroupPO extends BasePO {private String name;private String description;private List<Long> userIds;}

用户数据
在这里插入图片描述

用户组数据
在这里插入图片描述

 

条件查询

match:and 匹配
查询用户组 id 等于 1,且删除标识等于 N 的数据

db.getCollection("user_group").aggregate([{"$match": {"$and": [{"_id": NumberLong("1")}, {"deleteFlag": "N"}]}
}]);

match:or 匹配
查询用户 name 等于 nn 或者 description 等于 dd 的数据

db.getCollection("user").aggregate([{"$match": {"$or": [{"name": "nn"}, {"description": "dd"}]}
}]);

 

聚合查询

查询用户组里的用户详情

模糊查询

match:按规则匹配
regex:按正则匹配
实现:按 xxx 模糊匹配字段 userName 或者 按 xxx 模糊匹配字段 userDes

db.getCollection("user").aggregate([{"$match": {"$or": [{"userName": {"$regex": ".*xxx.*"}}, {"userDes": {"$regex": ".*xxx.*"}}]}
}]);

 

拆分数据

unwind:将文档中的某一个数组类型字段拆分成多条
实现:根据 userIds 把用户组拆分了多行

db.getCollection("user_group").aggregate([{"$match": {"$and": [{"_id": NumberLong("2809813774582045833")}, {"deleteFlag": "N"}]}
}, {"$unwind": "$userIds"
}]);

在这里插入图片描述
 

关联查询

根据用户组查询用户

lookup官方文档
lookup:关联查询,类似于 MySQL 的 left jion 效果
实现:根据用户组的 userIds 查询用户详情,注意:查出来的 user 是个数组

  • from:同一个数据库下等待被Join的集合。
  • localField:源集合中的match值,如果输入的集合中,某文档没有 localField
    这个Key(Field),在处理的过程中,会默认为此文档含
    有 localField:null的键值对。
  • foreignField:待Join的集合的match值,如果待Join的集合中,文档没有foreignField
    值,在处理的过程中,会默认为此文档含有 foreignField:null的键值对。
  • as:为输出文档的新增值命名。如果输入的集合中已存在该值,则会覆盖掉
db.getCollection("user_group").aggregate([{"$match": {"$and": [{"_id": NumberLong("4523281346310580824")}, {"deleteFlag": "N"}]}
}, {"$unwind": "$userIds"
}, {"$lookup": {"from": "user","localField": "userIds","foreignField": "_id","as": "user"}
}]);

在这里插入图片描述

 

根据用户查询用户组

lookup:关联查询,类似于 MySQL 的 left jion 效果
实现:查询用户列表且包含对应的用户组信息,注意:查出来的 userGroups 是个数组

  • from:要关联的从表名
  • let:自定义变量,可以为多个
  • pipeline:自定义的操作从表的聚合,但不允许使用out和merge操作,使用 let 定义的变量需要用两个$
  • as:为输出文档的新增值命名。如果输入的集合中已存在该值,则会覆盖掉
db.getCollection("user").aggregate([{$lookup: {from: "user_group",let: {user_id: "$_id"},pipeline: [{$match: {$expr: {$in: ["$$user_id", "$userIds"]}}}],as: "userGroups"}
}]);

在这里插入图片描述

 

控制显示

project 控制字段显示与否
实现: 删除无用字段,

  • 普通列({成员:1 | true}):表示要显示的内容
  • “_id” 列({“_id”:0 | false}):表示 “_id” 列是否显示
db.getCollection("user_group").aggregate([{"$match": {"$and": [{"_id": NumberLong("4523281346310580824")}, {"deleteFlag": "N"}]}
}, {"$unwind": "$userIds"
}, {"$lookup": {"from": "user","localField": "userIds","foreignField": "_id","as": "user"}
}, {"$project": {"user": 1,"_id": 0,}
}]);

在这里插入图片描述
 

字段置顶

arrayElemAt:将指定文档提升到顶级并替换所有其它字段。该操作会替换输入文档中的所有现在字段,包括_id字段
replaceRoot:返回存在于给定数组的指定索引上的元素
实现:把 user 的第一个元素提至顶级

db.getCollection("user_group").aggregate([{"$match": {"$and": [{"_id": NumberLong("4523281346310580824")}, {"deleteFlag": "N"}]}
}, {"$unwind": "$userIds"
}, {"$lookup": {"from": "user","localField": "userIds","foreignField": "_id","as": "user"}
}, {"$project": {"user": 1,"_id": 0,}
}, {"$replaceRoot": {"newRoot": {"$arrayElemAt": ["$user", 0]}}
}]);

在这里插入图片描述
此数据格式已经非常漂亮,符合日常返回格式,完成了需求

 

合并字段

mergeObjects:将多个文档合并为一个文档,如果要合并的文档包含相同的字段名,则结果文档中的字段具有该字段最后一个合并文档中的值
实现:保留 userGroup 的信息

db.getCollection("user_group").aggregate([{"$match": {"$and": [{"_id": NumberLong("4523281346310580824")}, {"deleteFlag": "N"}]}
}, {"$unwind": "$userIds"
}, {"$lookup": {"from": "user","localField": "userIds","foreignField": "_id","as": "user"}
}, {"$replaceRoot": {"newRoot": {"$mergeObjects": [{"$arrayElemAt": ["$user", 0]}, "$$ROOT"]}}
},{"$project": {"user": 0}
}]);

在这里插入图片描述
 

新增或修改字段

set:字段存在则修改,无则新增
实现:

db.getCollection("user_group").aggregate([{"$match": {"$and": [{"_id": NumberLong("4523281346310580824")}, {"deleteFlag": "N"}]}
}, {"$unwind": "$userIds"
}, {"$lookup": {"from": "user","localField": "userIds","foreignField": "_id","as": "user"}
}, {"$replaceRoot": {"newRoot": {"$mergeObjects": [{"$arrayElemAt": ["$user", 0]}, "$$ROOT"]}}
}, {"$project": {"user": 0}
}, {"$set": {"accounts": "accounts","deleteFlag": "deleteFlag"}
}]);

在这里插入图片描述
 

计算总数

count:计算总数
实现:查询 user 表的总条数

db.getCollection("user").aggregate([{"$count": "total"}
]);

在这里插入图片描述

 

分页查询

分页:对数据做分页处理
跳过 3 条数据,从第 4 条起,显示 2 条

  • skip:跳过多少条
  • limit:显示多少条
db.getCollection("user").aggregate([{"$skip": 3},{"$limit": 2}
]);

在这里插入图片描述
 

分页查询加总数

分页查询需要同时返回总数和数据
facet:在同一组输入文档的单一阶段中处理多个聚合管道;每个子管道在输出文档中都有自己的字段,其结果存储在文档数组中

db.getCollection("user").aggregate([{"$facet": {"metadata": [{"$count": "total"}],"records": [{"$skip": 0}, {"$limit": 10}]}}
]);

在这里插入图片描述
metadata 不太符合常规数据结构,把它去掉,把 total 提上顶层

db.getCollection("user").aggregate([{"$facet": {"metadata": [{"$count": "total"}],"records": [{"$skip": 0}, {"$limit": 2}]}},{"$replaceRoot": {"newRoot": {"$mergeObjects": [{"$arrayElemAt": ["$metadata", 0]}, "$$ROOT"]}}},{"$project": {"metadata": 0}}
]);

在这里插入图片描述
 

排序

sort:根据某字段对数据进行排序
其中 key 用来定义要根据那个字段进行排序,后面的值 1 则表示以升序进行排序,若要以降序进行排序则需要将其设置为 -1
实现:对用户表按创建时间倒序来排序

db.getCollection("user").aggregate([{$sort: {creationDate: - 1}}
]);

 

分组

$group :根据某字段对数据进行分组,类似 MySQL的 group by

  • _id :强制必须存在。可以为 null
  • $sum:计算总数
  • $avg:计算平均值
  • $max:最大值
  • $min:最小值
  • $first:输出第一个内容
  • $last:输出最后一个内容
  • $push:将数据拼接到一个数组中
  • $addToSet:将数据拼接到一个数组中,过滤重复数据

数据准备
在这里插入图片描述

 
$sum:根据用户的 userName 字段,对数据进行分组,并统计重复的总数

db.getCollection("user").aggregate([{$group: {_id: "$userName",count: {$sum: 1}}
}]);

在这里插入图片描述
 
$avg:根据用户的 userName 字段,对数据进行分组,并算出分组后 userDes 的平均值

db.getCollection("user").aggregate([{$group: {_id: "$userName",desavg: {$avg: "$userDes"}}
}]);

在这里插入图片描述
 
$push:根据用户的 userName 字段,对数据进行分组,并把 userDes 组合到 num

db.getCollection("user").aggregate([{$group: {_id: "$userName",num: {$push: "$userDes"}}
}]);

在这里插入图片描述
 
$addToSet:和push类似,但会过滤重复的数据,name2 的 40 只有一条了

db.getCollection("user").aggregate([{$group: {_id: "$userName",num: {$addToSet: "$userDes"}}
}]);

在这里插入图片描述
 
$$ROOT:分组后生成list

db.getCollection("user").aggregate([{$group: {_id: "$userName",num: {$push: "$$ROOT"}}
}]);

在这里插入图片描述

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

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

相关文章

mongodb查询

MongoDB 查询文档使用 find() 方法。 find() 方法以非结构化的方式来显示所有文档。 db.集合.find(query, projection) query &#xff1a;可选&#xff0c;使用查询操作符指定查询条件 projection &#xff1a;可选&#xff0c;使用投影操作符指定返回的键。查询时返回文档中所…

vue-element-admin实践系列(二)初始化系统的页面元素

vue-element-admin实践系列 vue-element-admin实践系列(一)代码部署及运行demovue-element-admin实践系列(二)初始化系统的页面元素 文章目录 vue-element-admin实践系列1、修改默认参数1.1 修改启动端口1.2 修改网页title1.3 修改网站 ico1.4 效果如下 2、自定义左侧导航栏2.…

一元多项式的加减法(C语言)

要求&#xff1a;以文件形式输入需要进行运算的两个一元多项式&#xff0c;并将结果以文件的形式进行输出。 #include<stdio.h> #include<stdlib.h> #include<math.h>//链表的构成 typedef struct Node{float ratio;int index;struct Node* next; }*PNode,*…

一元多项式计算器(C语言实现)

一、实验要求 二、代码实现 以下C语言代码实现了多项式的加减法、乘法、求导和顶点求值的功能。 &#xff08;水平有限&#xff0c;代码存在不规范之处&#xff09; 编程环境&#xff1a;Window11 Visual Studio #define _CRT_SECURE_NO_WARNINGS 1 # include <stdio.h…

c语言一元多项式课程设计,一元多项式的计算数据结构课程设计.doc

一元多项式的计算数据结构课程设计.doc 一元多项式的计算加&#xff0c;减摘要题目一元多项式计算任务能够按照指数降序排列建立并输出多项式&#xff1b;能够完成两个多项式的相加、相减&#xff0c;并将结果输入&#xff1b;目录1引言2需求分析3概要设计4详细设计5测试结果6…

基于C++的一元多项式相加

资源下载地址&#xff1a;https://download.csdn.net/download/sheziqiong/85996014 资源下载地址&#xff1a;https://download.csdn.net/download/sheziqiong/85996014 1.实验目的 了解链式存储结构的基本知识&#xff1b;掌握算法思想和数据结构的描述&#xff1b;结合一元…

c语言一元多项式相加

用单链表实现一元多项式相加 #include<stdio.h> #include<stdlib.h> typedef struct Node{float coef;//系数 int exp;//项数 struct Node *next; }LNode,*Linklist;void newPolynomial(Linklist &head){LNode *p;int i,tempExp;float tempCoef;scanf("…

一元多项式的相乘操作(链表)

一元多项式的乘法运算如何实现&#xff0c;要求多项式采用链表存储结构。 目录 基本思路&#xff1a; 添加条件的分类&#xff1a; multiple()源代码&#xff1a; detach()源代码&#xff1a; 处理结果&#xff1a; 基本思路&#xff1a; 本篇博客不知觉间已经拖了好久好久…

数据结构一元多项式的相加-单链表实现

实验内容&#xff1a;把任意给定的两个一元多项式P(x) ,Q(x) 输入计算机&#xff0c;计算它们的和并输出计算结果。 一元多项式可以用单链表表示&#xff0c;结点结构图示如下&#xff1a; coef expnext 首先分析一下这个过程是如何实现的 该算法需要求A与B两个一元多项式的和&…

一元多项式加减乘实现c/c++

一、实验题目&#xff1a; 一元多项式简单的计算器 1.主要功能&#xff1a; (1)输入并建立多项式&#xff1b; (2)输出多项式&#xff1b; (3)两个多项式相加&#xff0c;建立并输出和多项式&#xff1b; (4)两个多项式相减&#xff0c;建立并输出差多项式。 (5)算法的时…

一元多项式的加法

一元多项式的加法 问题描述&#xff1a;一元多项式的加法 &#xff08;1&#xff09; 编程实现一元多项式的加法。 &#xff08;2&#xff09; 编写一个测试主函数。 分析&#xff1a; 对于任意一元多项式 可以抽象为一个由“系数—指数”对构成的线性表&#xff0c;且线性表中…

一元多项式求导

问题描述&#xff1a; 设计函数求一元多项式的导数。&#xff08;注&#xff1a;x​n​​&#xff08;n为整数&#xff09;的一阶导数为nx​n−1​​。&#xff09; #include<cstdio> int main() {int a[100000];int b[100000];int n,m;char c;//判断结束的条件scanf(&q…

一元多项式课设

代码详见 目录 一、实习任务........................................................................................... - 1 - 1.问题描述&#xff1a;.................................................................................... - 1 - 2.小组分工.........…

数据结构:一元多项式及其基本运算

1、实现方式&#xff1a;可采用线性表的顺序存储结构&#xff0c;但是当多项式的每个项的指数差别很大时&#xff0c;会浪费很多存储空间。所以采用链式存储方式表示&#xff0c;每一项可以表示成一个结点&#xff0c;结点的结构由存放系数的coef域&#xff0c;存放指数的expn域…

一元多项式计算

目录 题目的内容及要求--------------------------------------------2需求分析-------------------------------------------------------2概要设计-------------------------------------------------------2 1、存储结构------------------------------------------------…

【数据结构】一元多项式的表示及相加

文章目录 ⭐️写在前面的话⭐️一元多项式的表示及相加初始化0_1、初始化链表0_2_1、头插法插入多项式的项(没有相同项)0_2_2、将要插入的相同&#xff0c;链表中有相同项&#xff0c;对应系数相加0_3、从链表中查找是否有相同的指数项0_4、对已经创建好的一元多项式按指数大小…

数据结构(严蔚敏)【一元多项式的运算】【C语言】

1、一元多项式的运算&#xff1a;实现两个多项式加、减乘运算 设计内容&#xff1a; 用顺序存储结构实现一元多项式的加法、减法和乘法。具体要求为&#xff1a;用五个函数分别实现一元多项式的创建、输出、加法、减法和乘法&#xff1b; 设计思路&#xff1a; 将顺序表数组…

算法竞赛入门【码蹄集进阶塔335题】(MT2151-2175)

算法竞赛入门【码蹄集进阶塔335题】(MT2151-2175&#xff09; 文章目录 算法竞赛入门【码蹄集进阶塔335题】(MT2151-2175&#xff09;前言为什么突然想学算法了&#xff1f;为什么选择码蹄集作为刷题软件&#xff1f; 目录1. MT2151 权值计算2. MT2152 黑客小码哥3. MT2153 来给…

Linux基础之LVM卷管理

LVM LVM是 Logical Volume Manager&#xff08;逻辑卷管理&#xff09;的简写&#xff0c;它是Linux环境下对磁盘分区进行管理的一种机制。Linux用户安装Linux操作系统时遇到的一个常见的难以决定的问题就是如何正确地评估各分区大小&#xff0c;以分配合适的硬盘空间。普通的…

linux lvcreate,LFCS:如何使用vgcreate,lvcreate和lvextend命令管理和创建LVM - 第11部分...

因为在LFCS考试要求有效的二月变化 2&#xff0c;2016年 &#xff0c;我们增加了必要的专题到LFCS系列发表在这里。 为了准备这场考试&#xff0c;你是高度鼓励使用联邦经济竞争法系列为好。 LFCS&#xff1a;管理LVM和创建LVM分区 - 第11部分 安装Linux系统时最重要的决定之一…