我爱编程华南理工大学无线电爱好者协会软件小组

MongoDB索引

2016-10-29  本文已影响0人  honehou

前言

在MongoDB中,索引通常能够极大的提高查询的效率。如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文档并选取那些符合查询条件的记录。如果有一个合适的索引来进行查询,则可以限制扫描文档的数量。
  索引是特殊的数据结构,存储在一个易于遍历读取的数据集合中,它是对数据库表中一列或多列的值进行排序的一种结构。索引条目的排序支持高效的匹配和基于范围的查询操作,同时,MongoDB可以通过使用索引返回排序后的结果。
  下面的示意图表明如何通过索引筛选和整理匹配的文档。($lt条件操作符表示小于,{score:-1或者1}表示逆向排序或者正向排序)

index-for-sort.png
  从本质上来说,MongoDB中的索引与其他数据库系统中的索引相类似,对于集合中的任何域或者子域都支持索引。

默认索引 _id

MongoDB在创建集合时,会在_id域创建一个唯一性的索引,即禁止插入两个具有相同_id值的文档,同时该索引无法被删除。

查询、创建、删除索引

//查询索引
db.集合名.getIndexes()
//创建索引
db. 集合名.createIndex( <key and index type specification>, <options> )
//删除索引
db.集合名.dropIndex(<key and index type specification>)

常见索引

{ 
"_id": ObjectId("570c04a4ad233577f97dc459"), 
"userid": 1,
"score": 1034, 
"location": { state: "NY", city: "New York" }
}

创建单键索引举例:

//这里的1不是值,而是代表排序方向,即升序
db.records.createIndex( { score: 1 } )
index-ascending
db.collection.createIndex( {userid:1, score:-1} )
// 查询时,支持对多个字段查询,也支持对单个字段查询
db.collection.find( { userid: "aa1" } )
db.collection.find( { userid: "ca2", score: { $gt: 60} } )
index-compound-key
1)排序顺序:
假设一个集合events的文档有两个字段usernamedate,使用下面两条不同的语句查询:
db.events.find().sort( { username: 1, date: -1 } )
db.events.find().sort( { username: -1, date: 1 } )

可支持上面两条查询语句的索引为:

db.events.createIndex( { "username" : 1, "date" : -1 } )

但是,该索引却不支持下面的查询:

db.events.find().sort( { username: 1, date: 1 } )

更多详情可参考 Use Indexes to Sort Query Results(需翻墙)
2)前缀:
索引前缀是复合索引字段的子集。例如,考虑下面的复合:
{ "item": 1, "location": 1, "stock": 1 }
它的索引前缀为:

{ item: 1 }
{ item: 1, location: 1 }

该复合索引可查询的方法有如下几种:

the item field,
the item field and the location field,
the item field and the location field and the stock field.

当然还有the item field and the stock field,因为item field是一个索引前缀,当然这样的效率不及直接用item field and the stock field作为一个复合索引。
但是,下面的查询方法是不支持的,因为缺少了item字段而不符合索引前缀。

the location field,
the stock field,
the location and stock fields.

如果建立了复合索引,同时有一个单键索引与它的复合索引重复,当它们没有稀疏或者唯一的属性时,可把单键索引删去。因为MongoDB会在能使用复合索引前缀的任何情况下优先用之。

db.collection.createIndex( { addr.zip: 1 } )
index-multikey
1)限制
多键索引不支持以下几种情况:分片键、哈希索引、覆盖查询。
对于复合多键索引,多个字段不能同时为数组,但允许其中一个字段为数组。
MongoDB无法直接使用整个数组作为查询条件,而是将数组的第一个元素作为查询条件,得到符合第一个元素的文档,返回给MongoDB,再使用第二个元素作为查询条件,直到得到最终结果。
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )

参考英文文档,由于英文水平不足,有些部分翻译会比较生硬。
如有建议,欢迎指出。

上一篇下一篇

猜你喜欢

热点阅读