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 ...
随机推荐
- Linux---CentOS 定时执行脚本配置
非常多时候我们有希望server定时去运行一个脚本来触发一个操作.比方使用七牛的工具上传,假设同步文件中面有新添加一个文件,这个时候我们能够提供定时脚本去完毕我们须要的同步命令(七牛的qrsbox工具 ...
- ajax中用jsonp接收json数据
最近在做查快递网页时遇到一个问题,调用的快递100的api,但是快递100api不允许跨域请求,就是用127.0.0.1发的请求会直接被拦截. 只是个简单的网页,不想自己做服务器转发,最后找到了一个y ...
- docker/qemu中是如何对设备管理的
文件系统中包括实际的磁盘中可读可写的. 容器中看到的设备是啥子呢?--docker qemu也是一样,在qemu中添加一个设备的物理意义是啥子嘛 其实设备也没啥好新奇的,不就是一个普通的文件么,然后在 ...
- setcookie函数
在任何请求的服务器响应都会有个头部,默认情况下,头部发送动作会在第一个输出发生时触发,如echo,<html>.(注:php有个header方法手动发送原生header) 由于setcoo ...
- Hibernate关联映射之_一对一
数据库模型 一般对一对一的关系而言,会存在一个主从关系.如 人 与 身份证,就是一个一对一关系, 人 是主,身份证 是从 Person PK:id name age Id_Card PK.FK:id ...
- 【题解】NOIP2016愤怒的小鸟
一眼n<=18状压dp……方程什么的都很显然,枚举两只小鸟,再将这条抛物线上的小鸟抓出来就好啦.只是这样O(n^3)的dp必然是要TLE的,我一开始这样交上去显然跑得巨慢无比,后来转念一想:面对 ...
- 2018牛客多校第一场 D.Two Graphs
题意: n个点,m1条边的图E1,n个点,m2条边的图E2.求图E2有多少子图跟图E1同构. 题解: 用STL的全排列函数next_permutation()枚举映射.对于每一种映射枚举每一条边判断合 ...
- C&C++——extern
1.C 调用C++的函数或变量 C 调用C++的函数或变量,在C++的头文件声明为extern "C" ,C调用的时候只使用extern 声明. 可见,extern "C ...
- 【AtCoder】ARC 081 E - Don't Be a Subsequence
[题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...
- [WC2007]剪刀石头布——费用流
比较有思维含量的一道题 题意:给混合完全图定向(定向为竞赛图)使得有最多的三元环 三元环条件要求比较高,还不容易分开处理. 正难则反 考虑,什么情况下,三元组不是三元环 一定是一个点有2个入度,一个点 ...