MongoDB多集合排序的一种实现
需求
假设有三个类型有所不同的表,saleorders、careorders、repairorders,表中有storeId信息,用于关联其所属的门店stores表,现在有个需求是要将这三个表集中展示在一个表格中展示。
实现
以下驱动使用mongoose实现,MongoDB版本大于3.6。
var orders = Store.aggregate([
{
$match: {_id: storeId},
},
{
$lookup: {
from: "saleorders",
let: {
storeId: storeId,
},
pipeline: [
{
$match: {
$expr: {
$eq: ['$storeId', '$$storeId'],
}
}
}
],
as:'sales'
}
},
{
$lookup: {
from: "careorders",
let: {
storeId: storeId
},
pipeline: [
{
$match: {
$expr: {
$eq: ['$storeId', '$$storeId']
}
}
}
],
as: 'cares'
}
},
{
$lookup: {
from: "repairorders",
let: {
storeId: storeId
},
pipeline: [
{
$match: {
$expr: {
$eq: ['$storeId', '$$storeId']
}
}
}
],
as: 'repairs'
}
},
{
$addFields: {
"repairs.orderType": '1',
"sales.orderType": '2',
"cares.orderType": '3',
}
},
{
$project: {
_id: 0,
items: {
$concatArrays: ['$repairs', '$cares', '$sales']
}
}
},
{$unwind: '$items'},
{
$replaceRoot: {
newRoot: '$items'
}
},
{$sort: {_id: -1 }},
])
这种实现的重点是使用一个排序集合之外的文档来关联这三个集合以及使用操作符$concatArrays来组合多个数组。常规的思路是,你要哪几个集合,就用那些集合进行关联,然后$unwind操作,但这种操作无法实现预期目的,因为$lookup是对每个文档进行对外关联。上述写法的思路是,假设几个集合的文档都集中在一个文档中的三个字段上,那么我们可以在单个集合上对数组合并排序。当然,前提第一步必须能找到一定会存在的唯一文档来实现关联,否则下面的步骤要不就关联不了,要不就关联多次,鉴于上面的操作是针对单个storeId的,所以必然能从stores集合中找到唯一的store文档进行关联。
当然,现实情况应该尽量避免这种方式来设计集合, 对于类型相似的文档应该放在同一个集合中,而且这种查询方式很可能出现聚合的中间步骤产生的数据量超过MongoDB限制(默认100M)的问题,应当使用allowDiskUse: true设置。
MongoDB多集合排序的一种实现的更多相关文章
- .Net中集合排序的一种高级玩法
背景: 学生有名称.学号, 班级有班级名称.班级序号 学校有学校名称.学校编号(序号) 需求 现在需要对学生进行排序 第一排序逻辑 按学校编号(序号)排列 再按班级序号排列 再按学生学号排列 当然,在 ...
- Java中对List集合排序的两种方法
第一种方法,就是list中对象实现Comparable接口,代码如下: public class Person implements Comparable<Person> { privat ...
- 用Java集合中的Collections.sort方法对list排序的两种方法
用Collections.sort方法对list排序有两种方法第一种是list中的对象实现Comparable接口,如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
- Java TreeSet集合排序 && 定义一个类实现Comparator接口,覆盖compare方法 && 按照字符串长度排序
package TreeSetTest; import java.util.Iterator; import java.util.TreeSet; import javax.management.Ru ...
- mongoDB之集合操作
mongoDB之集合操作 mongoDB中的集合相当于mysql中的表. mongoDB中集合的创建: 第一种方式:不限制集合大小 db.createCollection("集合名称&q ...
- 二维码扫描&集合排序
一.二维码扫描机制 二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的:在代码编制上巧妙地利用构 ...
- Java集合排序及java集合类详解--(Collection, List, Set, Map)
1 集合框架 1.1 集合框架概述 1.1.1 容器简介 到目前为止,我们已经学习了如何创建多个不同的对象,定义了这些对象以后,我们就可以利用它们来做一 ...
- Java8-用Lambda表达式给List集合排序
Lambda用到了JDK8自带的一个函数式接口Comparator<T>. 准备一个Apple类 public class Apple { private int weight; priv ...
- mongoDB 删除集合后,空间不释放
mongoDB 删除集合后,空间不释放,添加新集合,没有重新利用之前删除集合所空出来的空间,也就是数据库大小只增不减. 方法有: 1.导出导入 dump & restore 2.修复数据库 r ...
随机推荐
- 目标检测之Faster-RCNN的pytorch代码详解(数据预处理篇)
首先贴上代码原作者的github:https://github.com/chenyuntc/simple-faster-rcnn-pytorch(非代码作者,博文只解释代码) 今天看完了simple- ...
- beta版本冲刺六
目录 组员情况 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:恺琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内最新成果 团队签入记 ...
- cygwin上编译RPC框架thrift
cygwin的配置就不多说了,缺什么就通过安装器安装好了. 在thrift的官网下载 thrift-0.11.0源码,通过cmake编译,生成Makefile之后,make出现编译错误 /cygdri ...
- hadoop自定义数据类型
统计某手机数据库的每个手机号的上行数据包数量和下行数据包数量 数据库类型如下: 数据库内容如下: 下面自定义类型SimLines,类似于平时编写的model import java.io.DataIn ...
- web颜色转换为delphi
今天在写写一个日志浏览和报警功能时,要求用多种颜色去显示不同的信息,客户给出的颜色是web的 rgb颜色,就是用6位16进制数去表示的颜色,直接把他赋值给Delphi的TColor变量,发现显示的颜色 ...
- BZOJ2257 [Jsoi2009]瓶子和燃料 【裴蜀定理】
题目链接 BZOJ2257 题解 由裴蜀定理我们知道,若干的瓶子如此倾倒最小能凑出的是其\(gcd\) 现在我们需要求出\(n\)个瓶子中选出\(K\)个使\(gcd\)最大 每个数求出因数排序即可 ...
- GDB使用小记
By francis_hao Nov 7,2016 记录GDB常用功能. GDB可以让你查看一个程序在运行时其内部发生了什么,或者当一个程序崩溃时发生了什么(通过使用GDB查看core dum ...
- Mybatis LIKE模糊查询
1.在代码中拼接好字符串后传入进来 2.使用CONCAT在xml中拼接字符串: <if test="queryParam.keyword != null"> AND b ...
- NOIP2017宝藏 [搜索/状压dp]
NOIP2017 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘 ...
- Educational Codeforces Round 55 (Rated for Div. 2):E. Increasing Frequency
E. Increasing Frequency 题目链接:https://codeforces.com/contest/1082/problem/E 题意: 给出n个数以及一个c,现在可以对一个区间上 ...