插入测试数据

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. 谈谈react hooks的优缺点

    前言Hook 是 React 16.8 的新增特性.它是完全可选的,并且100%向后兼容.它可以让你使用函数组件的方式,运用类组件以及 react 其他的一些特性,比如管理状态.生命周期钩子等.从概念 ...

  2. java语言写一个建议的五子棋

    经过16天的java学习,也学得了不少关于Java方面的知识,我想分享一下我用java写的一个简单的五子棋. 游戏规则: (1)对局双方各执一色棋子.(2)空棋盘开局.(3)白先.黑后,交替下子,每次 ...

  3. 硬件篇-02-TX2刷机Jetpack4.3

    Jetson TX2收货将近一周了,期间趁摄像头还没到,预先给TX2配置了环境.由于学校要求写毕设日志,故干脆一起在知乎写了,顺带帮助想要给TX2配环境却苦于网络上关于TX2的教程很少的同学. 本期内 ...

  4. Android内核模块编译执行

    Author: GeneBlue 0X01 前言 内核驱动是漏洞的高发区,了解Android驱动代码的编写是分析.利用驱动漏洞的基础.本文以一个"hello"驱动为例,简单介绍内核 ...

  5. Linux文件共享服务之Vsftp

    目录 FTP Vsftp服务的搭建 ftp.sftp.vsftp.vsftpd的区别 FTP FTP的工作原理: FTP会话时包含了两个通道,一个叫控制通道,一个叫数据通道.控制通道是和FTP服务器进 ...

  6. Bettercap2.X版本的使用

    目录 Bettercap 安装 ARP欺骗 DNS 欺骗 注入脚本 结合Beef-XSS 替换下载文件 Bettercap 很多人应该都听过或者用过Ettercap,这是Kali下一款优秀的ARP欺骗 ...

  7. node-全局对象

    Node.js 全局对象 JavaScript 中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量. 全局对象与全局变量 global ...

  8. 【JavaScript】Leetcode每日一题-青蛙过河

    [JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...

  9. VS2017报错 由#define后的分号引发的【“ 应输入“)】

    其实并不是第十行分号出现了问题,而是由于在宏定义后面加了分号,修改成这样即可 一开始竟然没看出来--甚至以为是VS中出现"宏可以转换为constexpr"问题--下次要仔细--

  10. Nmap浅析(2)——端口发现

    端口发现 ​ 每台网络设备最多有216(65536)个端口,端口的作用是实现"一机多用".操作系统分了65536个端口号,程序在发送的信息中加入端口号,操作系统在接收到信息后按照端 ...