插入测试数据

db.inventory.insertMany( [
{ item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },
{ item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },
{ item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },
{ item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);

后面的栗子都会用到这里的测试数据

查询嵌套在数组中的文档

查询 instock 数组中包含  { warehouse: "A", qty: 5 }  的所有文档

> db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

嵌套文档内的字段,除了字段名、字段值一样,顺序也得一致,否则不匹配

精确匹配整个文档数组的栗子

> db.inventory.find({instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ]})
{ "_id" : ObjectId("60b6dbbf67b3da7412587548"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }

在文档数组中嵌入的字段上指定查询条件

在 instock 数组中,至少有一个文档的 qty 字段值是 ≤20 的

> db.inventory.find( { 'instock.qty': { $lte: 20 } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587547"), "item" : "notebook", "instock" : [ { "warehouse" : "C", "qty" : 5 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587548"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587549"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da741258754a"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

访问数组中文档的字段,如果不知道文档的准确索引值,只能按照以下格式

数组字段名.文档字段名
instock.qty

使用数组索引查询嵌入文档中的字段

上面的栗子是直接根据字段名查找

在 instock 数组中,第一个元素包含字段 qty ,且值 ≤20 的文档

> db.inventory.find( { 'instock.0.qty': { $lte: 20 } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587547"), "item" : "notebook", "instock" : [ { "warehouse" : "C", "qty" : 5 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da741258754a"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

在文档数组中的字段指定组合(多个)查询条件

栗子一

找到在 instock 数组中【至少有一个嵌入文档包含 qty > 10,以及至少有一个嵌入文档(但不一定是同一个嵌入文档)包含 qty ≤20 】的文档

> db.inventory.find( { "instock.qty": { $gt: 10,  $lte: 20 } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587548"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587549"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da741258754a"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }
  • 不需要在同一个文档同时满足两个条件(当然同一个文档同时满足也可以)
  • 只要整个文档数组中,两个条件都至少有一个满足的文档即可

栗子二

找到在 instock 数组中【至少有一个嵌入文档包含 qty = 5,以及至少有一个嵌入文档(但不一定是同一个嵌入文档)包含 warehouse = A 】的文档:

> db.inventory.find( { "instock.qty": 5, "instock.warehouse": "A" } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587549"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }

在文档数组中单个嵌套文档满足多个查询条件

前言

上面的栗子都是单个嵌套文档或多个嵌套文档满足多个查询条件即可

如果想确保单个嵌套文档必须同时满足多个查询条件呢?

使用 $elemMatch 运算符!(前面讲数组的时候也提到过)

栗子一

找到在 instock 数组【至少有一个包含 qty = 5 和 warehouse = A 的嵌入文档 】的文档

> db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

栗子二

找到在 instock 数组【至少有一个包含 qty > 10 且 ≤ 20 的嵌入文档】的文档

> db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587548"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da741258754a"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

MongoDB(12)- 查询嵌入文档的数组的更多相关文章

  1. mongodb批量更新操作文档的数组键

    persons文档的数据如下: > db.persons.find(){ "_id" : 2, "name" : 2 }{ "_id" ...

  2. MongoDB .Net Driver(C#驱动) - 内嵌数组/嵌入文档的操作(增加、删除、修改、查询(Linq 分页))

    目录 一.前言 1. 运行环境 二.前期准备工作 1. 创建 MongoDBContext MongoDb操作上下文类 2.创建测试类 3.创建测试代码 三.内嵌数组增加元素操作 1.Update.S ...

  3. mongodb 通过嵌入文档中的字段排序

    mongodb中的全部数据: db.testInfo.find({}) .sort({_id:-1}) .limit(100) 查询结果: /* 1 createdAt:2019/10/11 下午5: ...

  4. Spring Data MongoDB 五:进阶文档查询(分页、Morphia)(二)

    Spring Data MongoDB 三:基本文档查询(Query.BasicQuery)(一) 学习MongoDB 六: MongoDB查询(游标操作.游标信息)(三) 一.简单介绍 Spring ...

  5. MongoDB(9)- 文档查询操作之 find() 的简单入门

    find() MongoDB 中查询文档使用 find() find() 方法以非结构化的方式来显示所要查询的文档 语法格式 db.collection.find(query, projection) ...

  6. MongoDB学习笔记:文档Crud Shell

    MongoDB学习笔记:文档Crud Shell   文档插入 一.插入语法 db.collection.insertOne() 将单个文档插入到集合中.db.collection.insertMan ...

  7. MongoDB,无模式文档型数据库简介

    MongoDB的名字源自一个形容词humongous(巨大无比的),在向上扩展和快速处理大数据量方面,它会损失一些精度,在旧金山举行的MondoDB大会上,Merriman说:“你不适宜用它来处理复杂 ...

  8. Spring Data MongoDB 四:基本文档改动(update)(一)

    Spring Data MongoDB 三:基本文档查询(Query.BasicQuery)(一) 学习MongoDB 二:MongoDB加入.删除.改动 一.简单介绍 Spring Data  Mo ...

  9. MongoDB改动、删除文档的域属性实例

    MongoDB改动.删除文档的域属性实例 在站点的开发中,可能最初的设计不合理.或者后期业务的变更,会造成文档结构会有些无用的属性.须要去删除或改动.因为MongoDB 是无 Schema 的,不像关 ...

随机推荐

  1. Salesforce学习之路(四)利用Jenkins和Git实现Salesforce的CI/CD功能

    上文提到,基于CRM的二次开发是必不可少的,但是在实际项目中CI/CD是不可忽略的一个重要部分,与传统的Java,Python项目不同,如果对Salesforce进行持续集成和持续部署呢? 结合找到的 ...

  2. hdu 2841 Visible Trees(容斥)

    原文链接 There are many trees forming a m * n grid, the grid starts from (1,1). Farmer Sherlock is stand ...

  3. 【MySQL】若sql语句中order by指定了多个字段,则怎么排序?

    举个例子吧:order by id desc,time desc先是按 id 降序排列 (优先)如果 id 字段 有些是一样的话 再按time 降序排列 (前提是满足id降序排列)   order b ...

  4. 缓冲区溢出分析第09课:MS06-040漏洞研究——深入挖掘

    前言 经过前两次的分析,我们已经对Netapi32.dll文件中所包含的漏洞成功地实现了利用.在系统未打补丁之前,这确实是一个非常严重的漏洞,那么打了补丁之后,这个动态链接库是不是就安全了呢?答案是否 ...

  5. PAT 乙级 -- 1005 -- 继续(3n+1)猜想

    题目简述 卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂.        当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数.例如 ...

  6. Python2中的urllib、urllib2和 Python3中的urllib、requests

    目录 Python2.x中 urllib和urllib2 常用方法和类 Python3.x中 urllib requests Python2.x中 urllib和urllib2 urllib 和 ur ...

  7. Netcat瑞士军刀的简单使用

    目录 Netcat 常用参数: 常见的用法: 端口扫描: 聊天 文件传输 反弹shell 蜜罐 Netcat Netcat 常称为 nc,拥有"瑞士军刀"的美誉.nc 小巧强悍,可 ...

  8. POJ1325二分匹配或者DINIC(最小路径覆盖)

    题意:        有k个任务,两个机器,第一个机器有n个模式,第二个机器有m个模式,每个任务要么在第一个机器的一个模式下工作,要么在第二个机器的一个模式下工作,机器每切换一个模式需要重启一次,两个 ...

  9. Shiro反序列化漏洞复现

    Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.使用Shiro的易于理解的API,可以快速.轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企 ...

  10. Day009 冒泡排序

    冒泡排序 冒泡排序无疑是最为出名的排序算法之一,总共有八大排序! 冒泡排序的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知. 我们看到嵌套循环,应该立马就可以得出这个算法的 ...