内容简介:作为非关系型数据库中的佼佼者,MongoDB一大优势在于能够在一条文档中存储对象类型的数据,适当增加冗余来让数据库对于初创企业的技术团队来说,快速变动的需求导致没有必要花费过多精力设计关系严格的数据表,而是可以直接将相关联的数据字段放在一起,比如以下设计:如果使用类似关系型数据主键的将_id作为引用的方式如下:
作为非关系型数据库中的佼佼者,MongoDB一大优势在于能够在一条文档中存储对象类型的数据,适当增加冗余来让数据库 更好用 。文档中一个对象类型的字段在 MongoDB 中被称为 内嵌文档(Embedded) ,也是MongoDB推荐的存储形式。本文将基于官方文档介绍内嵌文档的查询方法。
1.内嵌文档的适用场景
对于初创企业的技术团队来说,快速变动的需求导致没有必要花费过多精力设计关系严格的数据表,而是可以直接将相关联的数据字段放在一起,比如以下设计:
db.books.insertMany( [ { _id: 1, name: "python", price: 25, size: { h: 14, w: 21}, reading: ["Tom","John"] }, { _id: 2, name: "mongo", price: 50, size: { h: 8.5, w: 11}, reading: ["John","Dave"] }, { _id: 3, name: "webGL", price: 80, size: { h: 8.5, w: 11}, reading: ["Lily"] }, ]); 复制代码
如果使用类似关系型数据主键的将_id作为引用的方式如下:
db.books.insertMany( [ { _id: 1, name: "python", price: 25, h: 14, w: 21, reading: ["Tom","John"] }, { _id: 2, name: "mongo", price: 50, h: 8.5, w: 11, reading: ["John","Dave"] }, { _id: 3, name: "webGL", price: 80, h: 8.5, w: 11, reading: ["Lily"] }, ]); db.reading.insertMany( [ { _id: 4, reader: "Tom", book_id:1 }, { _id: 5, reader: "John", book_id:1 }, { _id: 6, reader: "John", book_id:2 }, { _id: 7, reader: "Dave", book_id:2 }, { _id: 8, reader: "Lily", book_id:3 }, ]); 复制代码
相比之下,内嵌的方式有以下优点:
- 使用者查询次数减少 可以快速读取到比较完整的相关信息
- 使用字典对象和列表对象增加字段和成员都格外方便
内嵌文档可以降低字段修改对调用者的影响,比如在size字段下增加一个名为"l"的子字段表示书籍长度,对于调用者来说只需要在用到时从size对象中拿出来即可,不需要再去额外获取新的字段。 因此,在内嵌文档较小,更新频率不高时推荐使用内嵌文档来存储数据。
2.内嵌文档为字典的查询方法
以1中数据为例,对于单值的字段查询,只需要写一个 查询字典 (query filter)即可:
db.books.find( { price: 25 } ); 复制代码
当查询条件涉及内嵌文档中的子字段时,使用"."(可递进使用):
db.books.find( { "size.h": 8.5 } );//针对字典对象 -->[ { _id: 2, name: "mongo", price: 50, size: { h: 8.5, w: 11}, reading: ["John","Dave"] }, { _id: 3, name: "webGL", price: 80, size: { h: 8.5, w: 11}, reading: ["Lily"] }, ] db.books.find( { "reading.0": "Tom" } );//针对列表 -->[ { _id: 1, name: "python", price: 25, h: 14, w: 21, reading: ["Tom","John"] }, ] 复制代码
注意,不使用"."的话将会严格匹配内嵌文档:
db.books.find( { "size": { h: 8.5} } );//不存在size字段为{ h: 8.5}的文档 -->[] 复制代码
同普通查询一样,可以使用 运算符Query Operator :
db.books.find( { "size.w": { $lt: 21} } ); -->[ { _id: 2, name: "mongo", price: 50, size: { h: 8.5, w: 11}, reading: ["John","Dave"] }, { _id: 3, name: "webGL", price: 80, size: { h: 8.5, w: 11}, reading: ["Lily"] }, ] 复制代码
3.内嵌文档为列表的查询方法
示例数据
db.books.insertMany( [ { _id: 1, name: "python", price: 25, size: [14,21], reading: ["Tom","John"] }, { _id: 2, name: "mongo", price: 50, size: [8.5,11], reading: ["John","Dave"] }, { _id: 3, name: "webGL", price: 80, size: [8.5,11], reading: ["Lily"] }, ]); 复制代码
(1)指定列表{key:[value]} 列表必须符合value的条件
以1中数据为例,指定列表,将严格按照所有元素及其顺序查询:
db.books.find( { reading: ["Tom","John"]" }); -->[ { _id: 1, name: "python", price: 25, size: size: [14,21], reading: ["Tom","John"] }, ] 复制代码
若只要求指定元素存在且不要求顺序,使用 $all :
db.books.find( { reading: { $all: ["John"] } }); -->[ { _id: 1, name: "python", price: 25, size:[14,21], reading: ["Tom","John"] }, { _id: 2, name: "mongo", price: 50, size:[8.5,11], reading: ["John","Dave"] }, ] 复制代码
(2)指定元素{key:value1,value2...} 对于各个value的条件都至少有一个元素满足即可,不要求一个元素同时满足所有条件
db.books.find( { reading: "John" });//只要列表中有一元素的值为"John"即满足 -->[ { _id: 1, name: "python", price: 25, size:[14,21], reading: ["Tom","John"] }, { _id: 2, name: "mongo", price: 50, size:[8.5,11], reading: ["John","Dave"] }, ] db.books.find( { size: { $gt: 16, $lt: 15} });//只要列表中有一元素的值大于16,还有一元素小于15即满足 -->[ { _id: 1, name: "python", price: 25, size: [14,21], reading: ["Tom","John"] }, ] 复制代码
(3)指定元素{key:{$elemMatch:value1,value2...}} 只要至少有一元素同时符合各个value的条件
使用$elemMatch
db.books.find( { size: { $elemMatch: { $gt: 22, $lt: 30 } } }); -->[ { _id: 1, name: "python", price: 25, size: [14,21], reading: ["Tom","John"] }, ] 复制代码
(4)指定列表长度{key:{ $size: value... }}满足条件
使用$size
db.books.find( { reading: { $size: { $gt: 1} } }); -->[ { _id: 3, name: "webGL", price: 80, size: [8.5,11], reading: ["Lily"] }, ] 复制代码
总结,对于列表类型的内嵌文档,$elemMatch给出的并列条件要求至少有一个元素同时满足,不使用elemMatch时并列的条件只需要各自至少有一个元素满足即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- [ Laravel 5.7 文档 ] 数据库操作 —— 查询构建器
- 程序员必备(一):Dash,API 文档查询利器
- 程序员必备(一):Dash,API 文档查询利器
- bootstrap-select 的多选+模糊查询下拉框详解(官方示例文档解读)
- Mybatis关联查询(嵌套查询)
- MySQL高级查询---连接查询实例
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
亿级流量网站架构核心技术
张开涛 / 电子工业出版社 / 2017-4 / 99
《亿级流量网站架构核心技术》一书总结并梳理了亿级流量网站高可用和高并发原则,通过实例详细介绍了如何落地这些原则。本书分为四部分:概述、高可用原则、高并发原则、案例实战。从负载均衡、限流、降级、隔离、超时与重试、回滚机制、压测与预案、缓存、池化、异步化、扩容、队列等多方面详细介绍了亿级流量网站的架构核心技术,让读者看后能快速运用到实践项目中。 不管是软件开发人员,还是运维人员,通过阅读《亿级流......一起来看看 《亿级流量网站架构核心技术》 这本书的介绍吧!