MongoDB开发深入之二:索引
索引分类:
- 默认索引
- 单一索引
- 复合索引
- 多键索引(数组索引)
- 全文检索索引
- 2dsphere 索引
- 2D索引
- ......
索引属性:
- 到期TTL
- 唯一索引
- 部分索引
- 稀疏索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。特别在处理大量的数据时,查询甚至几分钟,这对网站的性能是非常致命的。
默认索引
默认情况下,所有集合都在_id 字段上有索引。
单一索引
一个名为records
的集合,它包含类似于以下 sample 文档的文档:
{
"_id": ObjectId("570c04a4ad233577f97dc459"),
"score": 1034,
"location": { state: "NY", city: "New York" }
}
以下操作在records
集合的score
字段上创建升序索引:
db.records.createIndex( { score: 1 } )
创建的索引将支持在字段score
上选择的查询,如下所示:
db.records.find( { score: 2 } )
db.records.find( { score: { $gt: 10 } } )
一个名为records
的集合,以下文档:
{
"_id": ObjectId("570c04a4ad233577f97dc459"),
"score": 1034,
"location": { state: "NY", city: "New York" }
}
以下操作在location.state
字段上创建索引:
db.records.createIndex( { "location.state": 1 } )
创建的索引将支持在字段location.state
上选择的查询,如下所示:
db.records.find( { "location.state": "CA" } )
db.records.find( { "location.city": "Albany", "location.state": "NY" } )
复合索引
一个名为products
的集合,它包含类似于以下文档的文档:
{
"_id": ObjectId(...),
"item": "Banana",
"category": ["food", "produce", "grocery"],
"location": "4th Street Store",
"stock": 4,
"type": "cases"
}
以下操作在item
和stock
字段上创建升序索引:
db.products.createIndex( { "item": 1, "stock": 1 } )
索引将包含首先按item
字段的值排序的文档的 references,并且在item
字段的每个 value 内,按 stock 字段的值排序。
一个包含username
和date
字段的文档的集合events
。 Applications 可以发出 return 结果首先按升序username
值排序,然后降序(i.e.更近期到最后)date
值的查询,例如:
db.events.find().sort( { username: 1, date: -1 } )
或者 return 结果首先按降序username
值排序,然后按升序date
值排序,例如:
db.events.find().sort( { username: -1, date: 1 } )
以下索引可以支持这两种排序操作:
db.events.createIndex( { "username" : 1, "date" : -1 } )
但是,上面的索引不能支持按升序username
值排序,然后升序date
值,如下所示:
db.events.find().sort( { username: 1, date: 1 } )
索引前缀
索引前缀是索引字段的起始子集。对于 example,请考虑以下复合索引:
{ "item": 1, "location": 1, "stock": 1 }
索引具有以下索引前缀:
{ item: 1 }
{ item: 1, location: 1 }
对于复合索引,MongoDB 可以使用索引来支持对索引前缀的查询。因此,MongoDB 可以在以下字段中使用索引进行查询:
item
字段,item
字段和location
字段,item
字段和location
字段以及stock
字段。
MongoDB 还可以使用索引来支持item
和stock
字段上的查询,因为item
字段对应于前缀。但是,索引在支持查询时效率不高,因为只有item
和stock
的索引。
但是,MongoDB 无法使用索引来支持包含以下字段的查询,因为没有item
字段,列出的字段中的任何一个都对应于前缀索引:
location
字段,stock
字段,或location
和stock
字段。
多键索引(数组索引)
MongoDB 会为 array 中的每个元素创建索引 key。这些多键索引支持对 array 字段的有效查询。可以在包含标量值(e.g .strings,numbers)和嵌套文档的数组上构建多键索引。
inventory
集合:
{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] }
{ _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] }
{ _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] }
{ _id: 8, type: "food", item: "ddd", ratings: [ 9, 5 ] }
{ _id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5 ] }
该集合在ratings
字段上有一个多键索引:
db.inventory.createIndex( { ratings: 1 } )
以下查询查找ratings
字段为 array [ 5, 9 ]
的文档:
db.inventory.find( { ratings: [ 5, 9 ] } )
MongoDB 可以使用多键索引查找ratings
array 中任何位置5
的文档。然后,MongoDB 为ratings
array 等于查询 array [ 5, 9 ]
的文档检索这些文档。
全文检索索引
MongoDB 提供文本索引以支持对 string 内容的文本全文搜索查询。 text索引可以包含 value 是 string 或 string 元素的 array 的任何字段。
2dsphere 索引
2dsphere索引支持计算 earth-like 球体上的几何的查询。 2dsphere index 支持所有 MongoDB 地理空间查询:包含,交集和邻近的查询。
以下操作在位置字段loc
上创建索引:
db.places.createIndex( { loc : "2dsphere" } )
位置索引的查询:
- GeoJSON Objects 由多边形限定
- GeoJSON Objects 的交集
- 靠近 GeoJSON 点
- 球体上定义的圆内点
以下 example 选择完全存在于 GeoJSON 多边形内的所有点和形状:
db.places.find( { loc :
{ $geoWithin :
{ $geometry :
{ type : "Polygon" ,
coordinates : [ [
[ 0 , 0 ] ,
[ 3 , 6 ] ,
[ 6 , 1 ] ,
[ 0 , 0 ]
] ]
} } } } )
到期TTL
TTL 索引是 MongoDB 可用于在一定量时间(秒)之后自动从集合中删除文档的特殊单一索引。
数据到期对于某些类型的信息非常有用,例如机器生成的 event 数据,日志和 session 信息,这些信息只需要在数据库中持续有限的 time 时间。
要创建 TTL 索引,请在 value 为日期的字段或包含date 值的 array 的字段上使用db.collection.createIndex()方法和expireAfterSeconds选项。
例如,要在eventlog集合的lastModifiedDate字段上创建 TTL 索引,请在mongo shell 中使用以下操作:
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
限制
- TTL 索引是 single-field 索引。 复合指数不支持 TTL 并忽略expireAfterSeconds选项。
- _id字段不支持 TTL 索引。
- 您无法在上限集合上创建 TTL 索引,因为 MongoDB 无法从上限集合中删除文档。
- 您不能使用createIndex()更改现有索引的expireAfterSeconds的 value。而是将collMod database 命令与指数 collection flag 结合使用。否则,要更改现有索引选项的 value,必须先删除索引并重新创建。
- 如果字段已存在 non-TTL single-field 索引,则无法在同一字段上创建 TTL 索引,因为您无法创建具有相同 key 规范且仅由选项不同的索引。要将 non-TTL single-field 索引更改为 TTL 索引,必须先删除索引并使用expireAfterSeconds选项重新创建。
唯一索引
唯一索引可确保索引字段不存储重复值;
在members
集合的user_id
字段上创建唯一索引:
db.members.createIndex( { "user_id": 1 }, { unique: true } )
部分索引
部分索引仅索引符合指定过滤器表达式的集合中的文档。通过索引集合中文档的子集,部分索引具有较低的存储要求,并降低了索引创建和维护的性能成本。
创建partial索引,请将db.collection.createIndex()方法与partialFilterExpression选项一起使用。 partialFilterExpression选项接受使用以下内容指定过滤条件的文档:
- 等式表达式(value或使用$eq operator),
- $exists:true表达,
- $gt,$gte,$lt,$lte表达式,
- $type表达式,
- 只有 top-level 的$and operator
该索引仅索引rating
字段大于 5 的文档。
db.restaurants.createIndex(
{ cuisine: 1, name: 1 },
{ partialFilterExpression: { rating: { $gt: 5 } } }
)
稀疏索引
稀疏索引仅包含具有索引字段的文档的条目,即使索引字段包含 null value 也是如此。索引会跳过缺少索引字段的任何文档。索引是“稀疏的”,因为它不包含集合的所有文档。相比之下,non-sparse 索引包含集合中的所有文档,为那些不包含索引字段的文档存储空值。
默认情况下稀疏的索引:
2 dsphere(version 2),2 d,geoHaystack和文本索引始终为稀疏索引。
以下操作会在addresses
集合的xmpp_id
字段上创建稀疏索引:
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
MongoDB开发深入之二:索引的更多相关文章
- [转载]MongoDB开发学习(2)索引的基本操作
索引能够极大的提高查询的效率.在数据库中简历索引必不可少. 在MongoDB中可以很轻松的创建索引. 默认索引_id_ 开启MongoDB服务器,创建数据库cnblogs,创建集合Users .(关于 ...
- Lucene.Net 2.3.1开发介绍 —— 三、索引(二)
原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(二) 2.索引中用到的核心类 在Lucene.Net索引开发中,用到的类不多,这些类是索引过程的核心类.其中Analyzer是索引建立的 ...
- 结合MongoDB开发LBS应用(转)
原文链接:结合MongoDB开发LBS应用 简介 随着近几年各类移动终端的迅速普及,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理.我所在 ...
- Python全栈开发【基础二】
Python全栈开发[基础二] 本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,f ...
- MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划
这篇文章主要介绍了MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划的相关资料,需要的朋友可以参考下 一.索引 MongoDB 提供了多样性的索引支持,索引信息被保存 ...
- [转]搭建高可用mongodb集群(二)—— 副本集
在上一篇文章<搭建高可用MongoDB集群(一)——配置MongoDB> 提到了几个问题还没有解决. 主节点挂了能否自动切换连接?目前需要手工切换. 主节点的读写压力过大如何解决? 从节点 ...
- 搭建高可用mongodb集群(二)—— 副本集
在上一篇文章<搭建高可用MongoDB集群(一)——配置MongoDB> 提到了几个问题还没有解决. 主节点挂了能否自动切换连接?目前需要手工切换. 主节点的读写压力过大如何解决? 从节点 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(二):成为开发者
Senparc.Weixin.MP SDK 微信公众平台开发教程(二):成为开发者 这一篇主要讲作为一名使用公众平台接口的开发者,你需要知道的一些东西.其中也涉及到一些微信官方的规定或比较掩蔽的注意点 ...
- Lucene.Net 2.3.1开发介绍 —— 三、索引(四)
原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(四) 4.索引对搜索排序的影响 搜索的时候,同一个搜索关键字和同一份索引,决定了一个结果,不但决定了结果的集合,也确定了结果的顺序.那个 ...
随机推荐
- Httpd服务入门知识-Httpd服务常见配置案例之虚拟主机
Httpd服务入门知识-Httpd服务常见配置案例之虚拟主机 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.虚拟主机实现方案 1>.Apache httpd 有三种实现虚 ...
- Linux无法免密登录的原因
一.免密登录的方法 下面操作是把/root/.ssh/id_dsa.pub文件内容追加到192.168.7.100系统中的/root/.ssh/authorized_keys文件中 # 创建并发送密钥 ...
- P5021 赛道修建[贪心+二分]
题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 mm 条赛道. C 城一共有 nn 个路口,这些路口编号为 1,2,-,n1,2,-,n,有 n-1n−1 条适合于修建赛道的双向通 ...
- 项目Beta冲刺(团队)——05.23(1/7)
项目Beta冲刺(团队)--05.23(1/7) 格式描述 课程名称:软件工程1916|W(福州大学) 作业要求:项目Beta冲刺(团队) 团队名称:为了交项目干杯 作业目标:记录Beta敏捷冲刺第1 ...
- 牛客NOIP暑期七天营-提高组2C:滑块(平衡树) (这里rope骗分)
A:hash 或者 map 或者trie. #include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) usin ...
- 27.SpringBoot和SpringMVC的区别
所以,用最简练的语言概括就是: Spring 是一个“引擎”: Spring MVC 是基于Spring的一个 MVC 框架: Spring Boot 是基于Spring4的条件注册的一套快速开发整合 ...
- JS的ES6的class
1.类的创建: 定义类 类的构造函数 类的静态方法 类的一般属性和方法 //定义类 class Person{ // 类的静态方法,相当于Person.test = function(){consol ...
- 【CSP-S膜你考】最近公共祖先 (数学)
Problem A. 最近公共祖先 (commonants.c/cpp/pas) 注意 Input file: commonants.in Output file: commonants.out Ti ...
- 使用Lua脚本通过原子减防止超卖
需求 双十二要搞一个一分钱门票抢购的活动. 分析 性能分析,抢购时会发生高并发,如果仅仅依靠Mysql数据库,有可能因为大量的请求频繁访问数据库造成服务器雪崩,所以考虑通过Redis减库存,最终的数据 ...
- 为arm-linux开发板挂载基于nfs的根文件系统
linux4.14内核,首先设置kernel的bootargs,在make menuconfig中有三种方式来配置: 第一种方式为如果uboot中设置了bootargs环境变量,就采用uboot的bo ...