索引分类:

  • 默认索引
  • 单一索引
  • 复合索引
  • 多键索引(数组索引)
  • 全文检索索引
  • 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"
}

以下操作在itemstock字段上创建升序索引:

db.products.createIndex( { "item": 1, "stock": 1 } )

索引将包含首先按item字段的值排序的文档的 references,并且在item字段的每个 value 内,按 stock 字段的值排序。

一个包含usernamedate字段的文档的集合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 还可以使用索引来支持itemstock字段上的查询,因为item字段对应于前缀。但是,索引在支持查询时效率不高,因为只有itemstock的索引。

但是,MongoDB 无法使用索引来支持包含以下字段的查询,因为没有item字段,列出的字段中的任何一个都对应于前缀索引:

  • location字段,

  • stock字段,或

  • locationstock字段。

多键索引(数组索引)

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开发深入之二:索引的更多相关文章

  1. [转载]MongoDB开发学习(2)索引的基本操作

    索引能够极大的提高查询的效率.在数据库中简历索引必不可少. 在MongoDB中可以很轻松的创建索引. 默认索引_id_ 开启MongoDB服务器,创建数据库cnblogs,创建集合Users .(关于 ...

  2. Lucene.Net 2.3.1开发介绍 —— 三、索引(二)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(二) 2.索引中用到的核心类 在Lucene.Net索引开发中,用到的类不多,这些类是索引过程的核心类.其中Analyzer是索引建立的 ...

  3. 结合MongoDB开发LBS应用(转)

    原文链接:结合MongoDB开发LBS应用 简介 随着近几年各类移动终端的迅速普及,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理.我所在 ...

  4. Python全栈开发【基础二】

    Python全栈开发[基础二] 本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,f ...

  5. MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划

    这篇文章主要介绍了MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划的相关资料,需要的朋友可以参考下 一.索引 MongoDB 提供了多样性的索引支持,索引信息被保存 ...

  6. [转]搭建高可用mongodb集群(二)—— 副本集

    在上一篇文章<搭建高可用MongoDB集群(一)——配置MongoDB> 提到了几个问题还没有解决. 主节点挂了能否自动切换连接?目前需要手工切换. 主节点的读写压力过大如何解决? 从节点 ...

  7. 搭建高可用mongodb集群(二)—— 副本集

    在上一篇文章<搭建高可用MongoDB集群(一)——配置MongoDB> 提到了几个问题还没有解决. 主节点挂了能否自动切换连接?目前需要手工切换. 主节点的读写压力过大如何解决? 从节点 ...

  8. Senparc.Weixin.MP SDK 微信公众平台开发教程(二):成为开发者

    Senparc.Weixin.MP SDK 微信公众平台开发教程(二):成为开发者 这一篇主要讲作为一名使用公众平台接口的开发者,你需要知道的一些东西.其中也涉及到一些微信官方的规定或比较掩蔽的注意点 ...

  9. Lucene.Net 2.3.1开发介绍 —— 三、索引(四)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(四) 4.索引对搜索排序的影响 搜索的时候,同一个搜索关键字和同一份索引,决定了一个结果,不但决定了结果的集合,也确定了结果的顺序.那个 ...

随机推荐

  1. Haproxy 让后端RS记录真实IP

    一.修改haproxy.cfg配置文件,在defaults中加入如下两行,并重启haproxy. vim /etc/haproxy/haproxy.cfg defaults option http-s ...

  2. 接口自动化--日志类封装(logging)

    上篇随笔已经写到了读取Excel类的封装了,下面就写下日志类, 日志类在我们自动化的过程中是十分重要的,在我们的自动化程序出现异常的时候就可以打印日志 下面是我自己封装的日志类 import logg ...

  3. 图论篇3——最短路径 Dijkstra算法、Floyd算法

    最短路径 问题背景:地图上有很多个城市,已知各城市之间距离(或者是所需时间,后面都用距离了),一般问题无外乎就是以下几个: 从某城市到其余所有城市的最短距离[单源最短路径] 所有城市之间相互的最短距离 ...

  4. Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code

    Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code 题目链接 题意: 给出\(n\)个俄罗斯套娃,每个套娃都有一个\( ...

  5. Elasticsearch Date类型,时间存储相关说明

    资料 网址 Elasticsearch 插入时间字段时数据格式问题 https://segmentfault.com/a/1190000016296983 Elasticsearch Date类型,时 ...

  6. CSS进阶之路

    下面主要引用http://www.cnblogs.com/wangfupeng1988/tag/css知多少/ CSS进阶笔记: 一.学习CSS的三个突破点 1.浏览器如何加载和解析CSS——CSS的 ...

  7. spark累加器、广播变量

    一言以蔽之: 累加器就是只写变量 通常就是做事件统计用的 因为rdd是在不同的excutor去执行的 你在不同excutor中累加的结果 没办法汇总到一起 这个时候就需要累加器来帮忙完成 广播变量是只 ...

  8. SpringBoot配置ThreadPoolTaskExecutor

    package com.example.demo; import org.springframework.context.annotation.Bean; import org.springframe ...

  9. afnetwork moya 都符合通信协议七层模型

    都是在会话层作出优化:安全.存储.会话控制: 在表示层作出数据处理: 在应用层提供请求响应的便捷接口.

  10. 使用Maven创建一个普通java项目

    1.创建项目: 使用Maven目的是是我们能够轻松的管理各种别人写过的包 创建好之后,我们去找我们所需要的包:在mvnrepository.com中找自己所需要的包 例子: 最后将依赖写入pom.xm ...