Java MongoDB project 多表查询 mongodb 多表联查

文章目录
一、聚合框架
二、 $lookup的功能及语法
三、案例
四.扩展查询
类似SQL中的on查询


一、聚合框架
聚合框架是MongoDB的高级查询语言,它允许我们通过转换和合并多个文档中的数据来生成新的单个文档中不存在的信息。

聚合管道操作主要包含下面几个部分:

命令 功能描述 备注

$project 指定输出文档里的字段
$match 选择要处理的文档,与fine()类似
$limit 限制传递给下一步的文档数量
$skip 跳过一定数量的文档
$unwind 扩展数组,为每个数组入口生成一个输出文档
$group 根据key来分组文档
$sort 排序文档
$geoNear 选择某个地理位置附近的的文档
$out 把管道的结果写入某个集合
$redact 控制特定数据的访问
$lookup 多表关联(3.2版本新增)

以下是$lookup的使用

二、 $lookup的功能及语法
1.主要功能 是将每个输入待处理的文档,经过$lookup 阶段的处理,输出的新文档中会包含一个新生成的数组列(户名可根据需要命名新key的名字 )。数组列存放的数据 是 来自 被Join 集合的适配文档,如果没有,集合为空(即 为[ ])

2.基本语法

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
3.语法的解释说明

4.注:null = null 此为真

其语法功能类似于下面的伪SQL语句

SELECT *, <output array field>
FROM collection
WHERE <output array field> IN (SELECT *
                               FROM <collection to join>
                               WHERE <foreignField>= <collection.localField>);
1.
2.
3.
4.
5.
三、案例
假设 有 订单集合, 存储的测试数据 如下
其中 item 对应 数据为 商品名称

db.orders.insertMany([
{ "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 },
{ "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 }
,{ "_id" : 3  }
]);
1.
2.
3.
4.
5.
db.inventory.insertMany([
   { "_id" : 1, "sku" : "almonds", description: "product 1", "instock" : 120 },
   { "_id" : 2, "sku" : "bread", description: "product 2", "instock" : 80 },
   { "_id" : 3, "sku" : "cashews", description: "product 3", "instock" : 60 },
   { "_id" : 4, "sku" : "pecans", description: "product 4", "instock" : 70 },
   { "_id" : 5, "sku": null, description: "Incomplete" },
   { "_id" : 6 }
]);
1.
2.
3.
4.
5.
6.
7.
8.
此集合中的 sku 数据等同于订单集合中的商品名称。
在这种模式设计下,如果要查询订单表对应商品的库存情况,应如何写代码呢?
很明显这需要两个集合Join。
接下来就是实际演示我们的关联查询的语句了:

db.orders.aggregate([
   {
     $lookup:
       {
         from: "inventory",
         localField: "item",
         foreignField: "sku",
         as: "inventory_docs"
       }
  }
])
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
结果:

{ "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2, "inventory_docs" : [ { "_id" : 1, "sku" : "almonds", "description" : "product 1", "instock" : 120 } ] }
{ "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1, "inventory_docs" : [ { "_id" : 4, "sku" : "pecans", "description" : "product 4", "instock" : 70 } ] }
{ "_id" : 3, "inventory_docs" : [ { "_id" : 5, "sku" : null, "description" : "Incomplete" }, { "_id" : 6 } ] }
1.
2.
3.
那如何实现内连接呢?实际上内连接只是需要过滤空值即可。

db.orders.aggregate([
   {
     $lookup:
       {
         from: "inventory",
         localField: "item",
         foreignField: "sku",
         as: "inventory_docs"
       }
  },
  {
      $match: { "item":{$ne:null}}
   }
])
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
四.扩展查询
类似SQL中的on查询
由于我们查询数据的时候常常不单单是要执行联表,联表常常伴随着过滤条件,那在本案例中怎么处理呢,比如我们不要item为空的,要模糊匹配item为p的数据:

db.orders.aggregate([
    {
       $match:{item:/p/}
    },
   {
     $lookup:
       {
         from: "inventory",
         localField: "item",
         foreignField: "sku",
         as: "inventory_docs"
       }
  }
])
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值