插入测试数据

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. 大一那会,我用QQ远程帮同学考过计算机二级

    考证 大一那会儿流行考证,什么普通话.教师资格证.计算机.商务英语各种证五花八门的. 我们非计算机专业(我是通信工程)的基本上都会去考一个叫计算机二级的证书,说是找工作有用,大一新生,哪懂这些,一窝蜂 ...

  2. 熟知Mysql基本操作

    本文是学习 Mysql必知必会 后的笔记 学习之前需要创建一个数据库,然后导入下面两个mysql脚本 create database db1 charset utf8; ############### ...

  3. 关于Redis客户端显示中文或中文乱码问题的解决

    关于Redis客户端不显示中文或者显示中文乱码,网上有些解决办法不全面的,都是漏了步骤不讲,简直瞎扯.在此记录一下解决方式. 刚开始使用Redis客户端的时候,本身就是默认不支持显示中文的. 例如,进 ...

  4. 常用head标签

    最小推荐 <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content= ...

  5. hdu4768 非常规的二分

    题意:       n个社团给同学发传单,同学一共有1--2^31这么多,每个社团有三个数A ,B ,C ,只有 满足 A ,A + C ,A + C + C ...A + KC <= B 的学 ...

  6. Xposed框架Hook Android应用的所有类方法打印Log日志

    本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80954759 在进行Android程序的逆向分析的时候,经常需要Android程 ...

  7. Tomcat容器、JSP和Servlet

    目录 JSP Tomcat.JSP和Servlet JSP JSP全名为Java Server Pages,其根本是一个简化的Servlet设计.JSP技术有点类似ASP技术,它是在传统的HTML网页 ...

  8. node-多进程

    Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能. 每个子进程总是带有三个流对象: child.stdin, ...

  9. [CTF]摩斯电码

    摩尔斯电码 -----------转载 https://morse.supfree.net/ 摩尔斯电码定义了包括:英文字母A-Z(无大小写区分)十进制数字0-9,以及"?"&qu ...

  10. <JVM上篇:内存与垃圾回收篇>01-JVM与Java体系结构

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...