在前面的分享中,有讲解 “详解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"的数据(子文档)。

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

MongoDB 集合间关联查询后通过$filter进行筛选的更多相关文章

  1. 详解MongoDB中的多表关联查询($lookup)

    一.  聚合框架 聚合框架是MongoDB的高级查询语言,它允许我们通过转换和合并多个文档中的数据来生成新的单个文档中不存在的信息. 聚合管道操作主要包含下面几个部分: 命令 功能描述 $projec ...

  2. Mongoose 两个表关联查询aggregate 以及 Mongoose中获取ObjectId

    Mongoose 两个表关联查询aggregate 通常两个表关联查询的时候,是一种一对多的关系,比如订单与订单详情就是一对多的关系,一个订单下面有多个商品 数据模拟 首先我们先将数据模拟出来,先选择 ...

  3. C#代码中实现两个表(DataTable)的关联查询(JOIN)

    之前通常都是使用SQL直接从数据库中取出表1和表2关联查询后的数据,只需要用一个JOIN就可以了,非常方便.近日遇到一种情况,两个表中的数据已经取到代码中,需要在代码中将这两个表关联起来,并得到它们横 ...

  4. Mybatis高级查询之关联查询

    learn from:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#Result_Maps 关联查询 准备 关联结果查询(一对一) resul ...

  5. mongodb操作之使用javaScript实现多表关联查询

    一.数据控制 mongodb操作数据量控制,千万控制好,不要因为操作的数据量过多而导致失败. 演示一下发生此类错误的错误提示:

  6. 一对一关联查询时使用relation连贯操作查询后,调用getLastSql()方法输出的sql语句

    如题: 一对一关联查询时使用relation连贯操作查询后,调用getLastSql()方法输出的sql语句不是一条关联查询语句. 例如: $list = $db->relation(true) ...

  7. 多表关联查询_resultMap_集合对象

    多表关联查询_resultMap_集合对象_N+1方式实现 package com.bjsxt.mapper; import java.util.List; import com.bjsxt.pojo ...

  8. mybatis映射文件select_resultMap_关联查询_collection定义关联集合

    知识点:查询一个实体类,并查出这个类下面的集合 Employee.java实体类 package com.hand.mybatis.bean;public class Employee {    pr ...

  9. MongoDB学习-->Gridfs分布式存储&DBRef关联查询

    mongodb自带的一个分布式文件系统 fs.files _id filename md5 size uploaddate contenttype metadata {"user_id&qu ...

随机推荐

  1. DRUID连接池配置详情

    DRUID介绍 DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0.DBCP.PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针 ...

  2. GeoServer中sld文件的获取来源

    众所周知,uDig是GeoServer的一个客户端,可以方便地可视化配置样式. QGIS行不行呢? 当然可以,双击图层名称,弹出图层属性对话框 在符号化(style)标签页选择样式导出即可. 参考博客 ...

  3. window下编译jcef

    自行编译jcef过程中遇到了一些问题,现在记录如下. 参考的主要文章是jcef的官方介绍: https://bitbucket.org/chromiumembedded/java-cef/wiki/B ...

  4. 使用 JWT 生成 Token 代码示例

    JSON Web Token,简称 JWT, 是一个开放的标准(RFC 7519),它定义了以一种紧凑的.自包含的 JSON 对象在各方之间安全传输信息的方式.该信息含有数字签名,可以被验证和信任. ...

  5. 来一波C#发送邮件

    1.所用工具和资源:VS2012   在.NET Frameword类库中提供SmtpClient类(System.NET.Mail) 2.运行截图 3.具体代码实现如下: using System; ...

  6. 第一周 IP通信基础学习回顾

    这周的课程首先让我们学习了计算机网络概述,了解计算机网络的定义和功能分别是:资源共享,信息传输与集中处理,负载均衡与分布处理,综合信息服务.同时也对计算机网络的演进,计算机网络的分类,计算机网络的性能 ...

  7. 【TensorFlow篇】--Tensorflow框架可视化之Tensorboard

    一.前述 TensorBoard是tensorFlow中的可视化界面,可以清楚的看到数据的流向以及各种参数的变化,本文基于一个案例讲解TensorBoard的用法. 二.代码 设计一个MLP多层神经网 ...

  8. 距离度量以及python实现(一)

    1. 欧氏距离(Euclidean Distance)        欧氏距离是最易于理解的一种距离计算方法,源自欧氏空间中两点间的距离公式. (1)二维平面上两点a(x1,y1)与b(x2,y2)间 ...

  9. dev treelist和searchcontrol组合模糊查询用法

    这里需要用到两个控件,是dev的treelist和searchcontrol,首先呢树形控件要形成树形我在这就不多说了 因为这里是记录下searchcontrol这控件的用法 首先写这三行代码,里面都 ...

  10. .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

    最近有个需求就是一个抽象仓储层接口方法需要SqlServer以及Oracle两种实现方式,为了灵活我在依赖注入的时候把这两种实现都给注入进了依赖注入容器中,但是在服务调用的时候总是获取到最后注入的那个 ...