首页 技术 正文
技术 2022年11月9日
0 收藏 482 点赞 3,289 浏览 2635 个字

在前面的分享中,有讲解 “详解MongoDB中的多表关联查询($lookup)” 一节,其内容涵盖了常见的集合管理的需求。我们知道文档的选择都是通过$match进行匹配刷选。但这是文档间的匹配筛选,并没有对单个新生成的文档进行内嵌子文档进行筛选。

那么什么是$lookup后新文档的内嵌子文档呢?

假设有以下2个集合,一个是商品库存集合 inventory,存储的测试数据 如下:

db.inventory.insert([
{ "_id" : 1, "sku" : "almonds", product: "product 1", "instock" : 120 },
{ "_id" : 2, "sku" : "bread1", product: "product 2", "instock" : 80 },
{ "_id" : 3, "sku" : "bread2", product: "product 2", "instock" : 80 },
{ "_id" : 4, "sku" : "pecans1", product: "product 4", "instock" : 70 },
{ "_id" : 5, "sku" : "pecans2", product: "product 4", "instock" : 70 },
])

一个是商品对应的原料集合product,存储的测试数据,如下。

db.product.insert([
{ "_id" : 1, product: "product 1", description: "金玉满堂1" },
{ "_id" : 2, product: "product 2", description: "招财进宝"},
{ "_id" : 3, product: "product 4", description: "杨柳依依"},
])

两个集合都包含有product 字段,如果 需求是按原料名称统计每个原料对应的商品情况。

可以根据字段product进行集合关联,并且product集合的文档与inventory 集合的文档是 一对多 的关系。

执行关联脚本查询的脚本如下:

db.product.aggregate([
{
$lookup:
{
from: "inventory",
localField: "product",
foreignField: "product",
as: "inventory_docs"
}
}
])

新生成的聚合集合的文档如下:

/* 1 */
{
"_id" : 1,
"product" : "product 1",
"description" : "金玉满堂1",
"inventory_docs" : [
{
"_id" : 1,
"sku" : "almonds",
"product" : "product 1",
"instock" : 120,
"state" : "OK"
}
]
},/* 2 */
{
"_id" : 2,
"product" : "product 2",
"description" : "招财进宝",
"inventory_docs" : [
{
"_id" : 2,
"sku" : "bread1",
"product" : "product 2",
"instock" : 80,
"state" : "OK"
},
{
"_id" : 3,
"sku" : "bread2",
"product" : "product 2",
"instock" : 80,
"state" : "Simple"
}
]
},/* 3 */
{
"_id" : 3,
"product" : "product 4",
"description" : "杨柳依依",
"inventory_docs" : [
{
"_id" : 4,
"sku" : "pecans1",
"product" : "product 4",
"instock" : 70,
"state" : "OK"
},
{
"_id" : 5,
"sku" : "pecans2",
"product" : "product 4",
"instock" : 70,
"state" : "Simple"
}
]
}

从返回结果可以看出,

(1) 返回的文档数量和.aggreate的集合文档数量一样(即外面的那个集合,而不是新字段的From的那个集合)。

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

注意新的字段的类型是数组的形式,一对多的时候,新字段就是就是明显的内嵌子文档。

我们看到新文档的字段 inventory_docs ,它由两个 内嵌 子文档组成,

"inventory_docs" : [
{
"_id" : 4,
"sku" : "pecans1",
"product" : "product 4",
"instock" : 70,
"state" : "OK"
},
{
"_id" : 5,
"sku" : "pecans2",
"product" : "product 4",
"instock" : 70,
"state" : "Simple"
}
]

那么如何根据要求筛选符合要求的子文档呢?$match是不可以的,这时候可以通过$filter。

代码如下:

db.product.aggregate([
{
$lookup:
{
from: "inventory",
localField: "product",
foreignField: "product",
as: "inventory_docs"
}
}
,
{
$project: {
inventory_docs: {
$filter: {
input: "$inventory_docs",
as: "item",
cond: { $eq: [ "$$item.state", "OK"
] }
}
}
}
}

])

结果显示如下:

/* 1 */
{
"_id" : 1,
"inventory_docs" : [
{
"_id" : 1,
"sku" : "almonds",
"product" : "product 1",
"instock" : 120,
"state" : "OK"
}
]
},/* 2 */
{
"_id" : 2,
"inventory_docs" : [
{
"_id" : 2,
"sku" : "bread1",
"product" : "product 2",
"instock" : 80,
"state" : "OK"
}
]
},/* 3 */
{
"_id" : 3,
"inventory_docs" : [
{
"_id" : 4,
"sku" : "pecans1",
"product" : "product 4",
"instock" : 70,
"state" : "OK"
}
]
}

从结果可以看出,数组子文档 没有了state:”Simple”的数据(子文档)。

本文版权归作者所有,未经作者同意不得转载,谢谢配合!!!

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,488
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,903
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,737
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,489
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,128
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,290