mongodb-多表联查与后续的数据处理

mongodb:3.6

数据

1,user表

{
    "_id" : ObjectId("5b69062240a6d80a6cece003"),
    "name" : "小明",
    "age" : 28,
    "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
    "_class" : "com.xiangpeng.bo.UserBo"
}

2,orders表

/* 1 */
{
    "_id" : ObjectId("5b69062240a6d80a6cece004"),
    "uid" : ObjectId("5b69062240a6d80a6cece003"),
    "money" : 10.0,
    "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
    "produce" : "产品1",
    "_class" : "com.xiangpeng.bo.OrderBo"
}

/* 2 */
{
    "_id" : ObjectId("5b6a5711c2eee4295c63768e"),
    "uid" : ObjectId("5b69062240a6d80a6cece003"),
    "money" : 20.0,
    "produce" : "产品2",
    "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
    "_class" : "com.xiangpeng.bo.OrderBo"
}

查询

1,mongodb的多表查询比较简单,使用$lookup关键字即可:

db.user.aggregate([{$lookup:{from:"orders",localField:"_id",foreignField:"uid",as:"orders"}}])

结果:

{
    "_id" : ObjectId("5b69062240a6d80a6cece003"),
    "name" : "小明",
    "age" : 28,
    "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
    "_class" : "com.xiangpeng.bo.UserBo",
    "orders" : [ 
        {
            "_id" : ObjectId("5b69062240a6d80a6cece004"),
            "uid" : ObjectId("5b69062240a6d80a6cece003"),
            "money" : 10.0,
            "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
            "produce" : "产品1",
            "_class" : "com.xiangpeng.bo.OrderBo"
        }, 
        {
            "_id" : ObjectId("5b6a5711c2eee4295c63768e"),
            "uid" : ObjectId("5b69062240a6d80a6cece003"),
            "money" : 20.0,
            "produce" : "产品2",
            "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
            "_class" : "com.xiangpeng.bo.OrderBo"
        }
    ]
}

参数解释:
form:需要关联的外表名,lookup的多变查询使用的是左外连接 localField:本表的外表关联字段; foreignField:外表的关联字段; as:参考查询结果,使用lookup进行查询后会将所有符合条件的文档封装为一个list,as参数定义这个list的名字;

数据处理

使用$unwind将数据打散:

db.user.aggregate([
        {$lookup:{from:"orders",localField:"_id",foreignField:"uid",as:"orders"},
        {$unwind:"$orders"}
])

$unwind的作用是将文档中的数组拆分为多条,拆分结果为:

/* 1 */
{
    "_id" : ObjectId("5b69062240a6d80a6cece003"),
    "name" : "小明",
    "age" : 28,
    "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
    "_class" : "com.xiangpeng.bo.UserBo",
    "orders" : {
        "_id" : ObjectId("5b69062240a6d80a6cece004"),
        "uid" : ObjectId("5b69062240a6d80a6cece003"),
        "money" : 10.0,
        "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
        "produce" : "产品1",
        "_class" : "com.xiangpeng.bo.OrderBo"
    }
}

/* 2 */
{
    "_id" : ObjectId("5b69062240a6d80a6cece003"),
    "name" : "小明",
    "age" : 28,
    "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
    "_class" : "com.xiangpeng.bo.UserBo",
    "orders" : {
        "_id" : ObjectId("5b6a5711c2eee4295c63768e"),
        "uid" : ObjectId("5b69062240a6d80a6cece003"),
        "money" : 20.0,
        "produce" : "产品2",
        "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
        "_class" : "com.xiangpeng.bo.OrderBo"
    }
}

数据过滤

现在可以对数据进行过滤,数据过滤的步骤应该尽可能提前,但如果过滤条件中也需要筛选外表条件的话就没办法放前面了,过滤在聚合中使用$match

db.user.aggregate([
    {$lookup:{from:"orders",localField:"_id",foreignField:"uid",as:"orders"}},
    {$unwind:"$orders"},
    {$match:{name:"小明","orders.produce":"产品2"}}
])

查出小明买的产品2订单
结果展示

/* 1 */
{
    "_id" : ObjectId("5b69062240a6d80a6cece003"),
    "name" : "小明",
    "age" : 28,
    "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
    "_class" : "com.xiangpeng.bo.UserBo",
    "orders" : {
        "_id" : ObjectId("5b6a5711c2eee4295c63768e"),
        "uid" : ObjectId("5b69062240a6d80a6cece003"),
        "money" : 20.0,
        "produce" : "产品2",
        "createtime" : ISODate("2018-08-07T02:38:26.601Z"),
        "_class" : "com.xiangpeng.bo.OrderBo"
    }
}

如果对字段结果有要求可以使用$project进行字段筛选:

db.user.aggregate([
    {$lookup:{from:"orders",localField:"_id",foreignField:"uid",as:"orders"}},
    {$unwind:"$orders"},
    {$match:{name:"小明","orders.produce":"产品2"}},
    {$project:{name:"$name",age:"$age",produce:"$orders.produce",money:"$orders.money"}}])

再聚合中$可以用作引用相应字段的值
结果为:

/* 1 */
{
    "_id" : ObjectId("5b69062240a6d80a6cece003"),
    "name" : "小明",
    "age" : 28,
    "produce" : "产品2",
    "money" : 20.0
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 简介 MongoDB 是一个基于分布式文件存储的NoSQL数据库 由C++语言编写,运行稳定,性能高 旨在为 WE...
    大熊_7d48阅读 37,827评论 1 9
  • 1、聚合查询 聚合查询主要使用聚合框架对集合中的文档进行变换与组合,以实现对文档的一连串处理。这些处理包含筛选(F...
    桥头放牛娃阅读 5,281评论 1 51
  • 什么是Mongodb数据库? MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统 Mo...
    瘦不下去了阅读 3,890评论 0 0
  • 1. MongoDB 简介 MongoDB是一个可扩展的高性能,开源,模式自由,面向文档的NoSQL,基于分布式文...
    rhlp阅读 4,865评论 0 3
  • 简介 NoSQL : 全名为Not Only SQL, 指的是非关系型的数据库 随着访问量上升, 网站的数据库性能...
    奋斗的老王阅读 8,213评论 4 47

友情链接更多精彩内容