mongodb 中的Multikey Index Bounds解释$elemMatch
首先说一下 $elemMatch的用法:
{ _id: 1, results: [ 82, 85, 88 ] }
{ _id: 2, results: [ 75, 88, 89 ] }
$elemMatch是匹配document 中数组中至少有一个元素满足$elemMatch中的所有条件,例如:
db.scores.find(
{ results: { $elemMatch: { $gte: 80, $lt: 85 } } }
) 查询结果为: { "_id" : 1, "results" : [ 82, 85, 88 ] } 结下来解释一下(Multikey Index Bounds):
在一个查询期间,索引的扫描范围定义了部分索引为了搜索,当多个(条件)predicates 超过一个索引存在时:mongodb 将试图去合并这些(条件)predicates的边界,要么通过求交集的方法合并
要么通过组合的方法,为了去产生一个比较小的扫描范围。给定一个索引数组字段,考虑到在一个查询中,在一个数组中指定了多个(条件)predicates并且可以使用 Multikey Index。
if $elemMatch 中有多个(条件)predicates ,mongodb会合并 Multikey Index的边界。因此,会有$elemMatch是匹配document 中数组中至少有一个元素满足$elemMatch中的所有条件。 继续上面的例子,逐个条件边界的范围:
大于等于80($gte:80)的边界为[80,inf];
小于85($lt:85)的边界为[-inf,85]。
由于使用了$elemMatch组织多个条件查询,mongodb查询的边界为results:[[80,85)]。 我们在来看一下(Compound Bounds for Multikey Index) 由于上面的查询条件可以求交集,但是,假如还有一种情况,有两个数组:
{ _id: 1, results: [ 82, 85, 88 ],scores:[66,77,88] }
{ _id: 2, results: [ 75, 88, 89 ] ,scores:[77,44,22]}
查询条件为:
db.scores.find(
{ results: { $gte: 85 },scores:{$lt:60}}
)
他们是没有交集的,在这种情况下,索引的边界是怎么样的呢?就继续看 Compound Bounds for Multikey Index
把同一个数组中的不同索引键的边界混合在一起的条件如下:
这些索引的keys必须有相同的字段路径,但是不包括字段的names
这个查询必须在指定的字段路径的这个特定的字段上面使用$elemMatch
还是看例子:
{
_id: 1,
item: "ABC",
ratings: [ { score: 2, by: "mn" }, { score: 9, by: "anon" } ]
}
{
_id: 2,
item: "XYZ",
ratings: [ { score: 5, by: "anon" }, { score: 7, by: "wv" } ]
}
创建索引:
db.survey2.createIndex( { "ratings.score": 1, "ratings.by": 1 } )
查询语句:
db.survey2.find( { ratings: { $elemMatch: { score: { $lte: 5 }, by: "anon" } } } )
逐个索引分析:
score {$lte:5}的边界是:[-inf,5],
by {by:"anon"}的边界是:["anon":"anon"]
mongodb 索引混合的结果为:
{ "ratings.score" : [ [ -Infinity, 5 ] ], "ratings.by" : [ [ "anon", "anon" ] ] }
再看一个例子:
{
_id: 1,
item: "ABC",
ratings: [
{ score: { q1: 2, q2: 5 }, certainty: { q1: 2, q2: 3 } },
{ score: { q1: 8, q2: 4 }, certainty: { q1: 10, q2: 10 } }
]
}
{
_id: 2,
item: "XYZ",
ratings: [
{ score: { q1: 7, q2: 8 }, certainty: { q1: 5, q2: 5 } },
{ score: { q1: 9, q2: 5 }, certainty: { q1: 7, q2: 7 } }
]
}
创建的索引为:
db.survey4.createIndex( {
"ratings.score.q1": 1,
"ratings.score.q2": 1,
"ratings.certainty.q1": 1,
"ratings.certainty.q2": 1
} )
查询的语句为:
db.survey4.find(
{
"ratings.score": { $elemMatch: { q1: 5, q2: 5 } },
"ratings.certainty": { $elemMatch: { q1: 7, q2: 7 } },
}
但是,当$elemMatch不能连接"ratings.score"和"ratings.certainty",mongodb 不能混合它们两个的边界,然而,mongodb 强制领导索引字段"ratings.score.q1" 和 "ratings.score.q2"的边界混合。
边界的混合结果如下:
{
"ratings.score.q1" : [ [ 5, 5 ] ],
"ratings.score.q2" : [ [ 5, 5 ] ],
"ratings.certainty.q1" : [ [ MinKey, MaxKey ] ],
"ratings.certainty.q2" : [ [ MinKey, MaxKey ] ]
}
mongodb 中的Multikey Index Bounds解释$elemMatch的更多相关文章
- Spring中映射Mongodb中注解的解释
spring-data-mongodb中的实体映射是通过MongoMappingConverter这个类实现的.它可以通过注释把java类转换为mongodb的文档. 它有以下几种注释: @Id - ...
- Mongodb中Sharding集群
随着mongodb数据量的增多,可能会达到单个节点的存储能力限制,以及application较大的访问量也会导致单个节点无法承担,所以此时需要构建集群环境,并通过sharding方案将整个数据集拆分成 ...
- 使用aggregate在MongoDB中查找重复的数据记录
我们知道,MongoDB属于文档型数据库,其存储的文档类型都是JSON对象.正是由于这一特性,我们在Node.js中会经常使用MongoDB进行数据的存取.但由于Node.js是异步执行的,这就导致我 ...
- spring data mongodb中,如果对象中的属性不想加入到数据库字段中
spring data mongodb中,如果对象中的属性不想加入到数据库字段中,可加@Transient注解,声明为透明属性 spring data mongodb 官网帮助文档 http://ww ...
- 分析AJAX抓取今日头条的街拍美图并把信息存入mongodb中
今天学习分析ajax 请求,现把学得记录, 把我们在今日头条搜索街拍美图的时候,今日头条会发起ajax请求去请求图片,所以我们在网页源码中不能找到图片的url,但是今日头条网页中有一个json 文件, ...
- Mongodb中 Documents文档说明
mongodb使用BSON格式存储数据记录. 如下图: 文档结构 文档有键值对组成, 有以下结构: { field1: value1, field2: value2, ... ...
- MongoDB中的explain和hint提的使用
一.简介 这里简单介绍一下各个工具的使用场景,一般用mysql,redis,mongodb做存储层,hadoop,spark做大数据分析. mysql适合结构化数据,类似excel表格一样定义严格的数 ...
- 在MongoDB中执行查询、创建索引
1. MongoDB中数据查询的方法 (1)find函数的使用: (2)条件操作符: (3)distinct找出给定键所有不同的值: (4)group分组: (5)游标: (6)存储过程. 文档查找 ...
- mongodb中查询返回指定字段
mongodb中查询返回指定字段 在写vue项目调用接口获取数据的时候,比如新闻列表页我只需要显示新闻标题和发表时间,点击每条新闻进入详情页的时候才会需要摘要.新闻内容等关于此条新闻的所有字段. ...
随机推荐
- Android WebView ScrollBar设置
WebView wv; wv.setVerticalScrollBarEnabled(false); 取消Vertical ScrollBar显示 wv.setHorizontalScrollBar ...
- MySQL的limit子句
1.理解: limit用来取结果集中的固定几条记录 2.参数: limit offset,pagesize offset:偏移量,为0时,可以省略 pagesize:每页显示的行数,通常是固定的 0表 ...
- IOS时间与日期处理
本文转载至 http://blog.sina.com.cn/s/blog_9cd1705d0102v5x4.html 主要有以下类: NSDate -- 表示一个绝对的时间点NSTimeZone ...
- web容器 web服务器 servlet/jsp容器 之间的区别和关系是什么?
web容器 web服务器 servlet/jsp容器 之间的区别和关系是什么? 这是我在网上找的一些资料:1. Web浏览器除了可以在本地硬盘上打开网页文档外,还可以使用http网络协议从网络上的We ...
- docker openvas
https://hub.docker.com/r/mikesplain/openvas/ Requirements DockerPorts available: 443, 9390, 9391 Usa ...
- Python3.6全栈开发实例[014]
14.好声音选秀大赛评委在打分的时,可以进行输入. 假设,有10个评委.让10个评委进行打分, 要求, 分数必须大于5分, 小于10分. count = 1 while count <= 10: ...
- locust参数化
前面用篇专门讲了requests实现接口的参数关联案例,这里直接转化成locust脚本就行了 # coding:utf-8 from locust import HttpLocust, TaskSet ...
- Linux中对启动过程中选择启动级别那个界面设置密码
生成md5形式的密码: a.执行 grub-md5-crypt 命令 b.在接下来的交互界面中输入自己的密码 c.生成加密后的密码修改配置文件: a.vi /boot/grub/grub.conf ...
- django自带的用户认证和form表单功能
一.用户认证 1.用户认证方法 1.ajango自带用户认证功能,只需要引入相应的模块就可以使用,但是前提是必须使用ajango自带的auth_user表,并且需要把用户相关信息存放在该表中. 2.引 ...
- VS 无法调试 IIS
用附加的方式断点无效时. 解决方案: 一.VS设置的 .Net版本 与 IIS应用程序池的版本 不一致. 操作步骤: 1. 在VS-> 项目属性, 配置 自定义Web服务器 , 这里 ...