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 ... 
随机推荐
- UZH slam 两种相机
			1.event camera:http://rpg.ifi.uzh.ch/research_dvs.html 2.SCAMP Vision Sensor:https://personalpages.m ... 
- TF-IDF与主题模型 - NLP学习(3-2)
			分词(Tokenization) - NLP学习(1) N-grams模型.停顿词(stopwords)和标准化处理 - NLP学习(2) 文本向量化及词袋模型 - NLP学习(3-1) 在上一篇博文 ... 
- 传统IT七大职业的云计算转型之路
			毫无疑问,对于那些传统IT技术--企业架构师.系统管理者.测试验收工程师或者网络工程师等开发人员骑身到云计算行业不仅是大势所趋,也能为其带来工作的保证,薪酬也更加丰厚. 如今,企业上云已经成为不可阻挡 ... 
- java线程(6)——线程池(下)
			上篇博客java线程(5)--线程池(上)介绍了线程池的基本知识,这篇博客我们介绍一下常用的ThreadPoolExecutor. 定义 类图关系: ThreadPoolExecutor继承了Abst ... 
- 从零开始配置Jenkins(三)——用户权限管理
			背景 最近项目管理中需要对jenkins的权限进行区分和限定,就研究了一下下.顺道把用户和权限这块的内容分享给大家. 用户 要想创建用户,需要先设定允许用户注册. 在系统设置,Configure Gl ... 
- 玩lua
			https://my.oschina.net/wangxuanyihaha/blog/186401 
- Foundation框架-NSCalendar
			NSCalendar 日历类 Cocoa中对日期和时间的处理 NSCalendar (一) (2008-11-12 21:54:10) NSCalendar用于处理时间相关问题.比如比较时间前后.计算 ... 
- NAPT 分为锥型(Cone)和 对称型(Symmetric)
			NAPT 分为锥型(Cone)和 对称型(Symmetric) 链接:https://www.zhihu.com/question/38729355/answer/86531260 实际上大部运营商提 ... 
- 【题解】NOI2014动物园
			传送门:洛谷P2375 一直到写到这道题目才发现我一直都理解了假的KMP……fail数组:fail[i]为从1-i(包含i)在内的字符串,相同的最长前后缀长度. 那么我们可以先思考暴力:先求出所有的f ... 
- [Leetcode] Length of last word 最后一个单词的长度
			Given a string s consists of upper/lower-case alphabets and empty space characters' ', return the le ... 
