Index
定义
索引,一个单独的、存储在磁盘上的数据结构
mongodb 的索引采用 B-tree 数据结构存储
-
易于遍历,支持相等匹配和范围查询
-
存储字段的值以及指向其所在文档的指针
包含集合中所有文档的指针(包含数据表中所有记录的引用指针)
-
按字段的值排序
mongodb index
- 在集合级别定义索引,支持在文档中的任何字段或子字段上建立索引
- 给某个字段添加索引,可以快速找出在该字段有特定值的文档,提高查询速度
- 如果没有索引,mongodb必须扫描集合中所有的文档,以选择那些符合查询条件的文档。一般而言,在查询文档时应避免扫描全部文档,这样会使查询速度非常慢
- 建立索引可以缩小mongodb扫描文档的数量,提高查询速度
- mongodb 可以返回基于索引排序的查询结果
演示基于索引查询并排序
_id
- mongodb 默认会为文档创建一个
_id 字段,并建立唯一索引
- 不能删除建立在
_id字段上的索引
- 索引名称为
_id_
创建索引
db.collection.createIndex
-
为集合创建索引
-
如果索引(名称)已经存在,则不会再次创建
-
除 collation 选项外,使用 不同的选项 不会创建 具有相同索引规范的 索引,也不会修改这些选项的值
只能删除之前的索引,重新使用新的选项创建
-
使用不同的 collation 选项,可以创建 多个 具有相同的索引规范的 索引,但是需要指定 唯一的 索引名称
db.person.createIndex({name:1},{name:"a_c", collation:{locale:"fr"}})
db.person.createIndex({name:1},{name:"a_b", collation:{locale:"fa"}})
-
如果文档不包含指定的字段,则操作失败
格式
db.collection.createIndex(keys, options)
Returns
-
成功
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 3,
"numIndexesAfter" : 4,
"ok" : 1
}
- createdCollectionAutomatically 是否自动创建集合
- numIndexesBefore 创建之前索引个数
- numIndexesAfter 创建之后索引个数
- ok:1 创建成功
-
失败
{
"ok" : 0,
"errmsg" : "Error: hashed indexes do not currently support array values",
"code" : 16766,
"codeName" : "Location16766"
}
- ok:0 创建失败
- errmsg 失败信息
- code 失败码
- codeName ?
查询索引
db.collection.getIndexes
-
查询集合中所有的索引信息
-
返回一个数组,数组元素是描述索引信息的文档
索引信息包括创建索引时的信息:keys 以及 options
格式
db.collection.getIndexes()
db.collection.totalIndexSize
- 查询集合中所有索引的大小
- 如果索引使用前缀压缩 (这是WiredTiger的默认值),则返回压缩后的大小
- 单位 字节 byte
格式
db.collection.totalIndexSize()
删除索引
db.collection.dropIndex
- 删除指定索引
- 不能删除默认创建在
_id 字段上的索引
格式
db.collection.dropIndex(index)
排它锁
- 4.2 版本之前,dropIndex 操作在父级数据库上获取一个排它锁,阻塞所有对数据库及其所有集合的操作,直到操作完成
- 4.2 版本之后,dropIndex 操作在指定集合上获取一个排它锁,阻塞对集合的所有后续操作
示例
de.collection.dropIndexes
- 删除单个或多个索引
- 不能删除默认创建在
_id 字段上的索引
格式
db.collection.dropIndex(indexes)
-
indexes
-
类型:字符串、文档、字符串数组
-
描述:需要删除的索引
排它锁
- 4.2 版本之前,dropIndex 操作在父级数据库上获取一个排它锁,阻塞所有对数据库及其所有集合的操作,直到操作完成
- 4.2 版本之后,dropIndex 操作在指定集合上获取一个排它锁,阻塞对集合的所有后续操作
示例
-
删除_id之外的所有索引
db.collection.dropIndexes()
-
删除单个索引
db.collection.dropIndexes( { a: 1, b: 1 } )
db.collection.dropIndexes( "a_1_b_1" )
-
删除多个索引
db.collection.dropIndexes( [ "a_1_b_1", "a_1", "a_1__id_-1" ] )
索引类型
Single Field 索引
- 单字段索引
- 对于单字段索引,升序降序并不重要,因为mongodb可以按任意方向遍历索引
示例
db.collection.createIndex( { orderDate: 1 } )
- 在 orderDate 字段上创建一个升序索引
- 默认名称
orderDate_1
Compound 索引
示例
db.collection.createIndex( { orderDate: 1, zipcode: -1 } )
- 创建一个在 orderDate 字段进行升序排列,在 zipcode 字段进行降序排列的复合索引
Multikey 索引
- 多键索引
- 使用点表示法,对嵌套数组中的字段建立索引
- mongodb会为数组中的每个元素创建单独的 索引项
- 允许查询条件匹配数组的一个或多个元素来选择符合条件的文档
- 如果索引字段包含数组元素,mongodb会自动创建一个多键索引
Geospatial 索引
Text 索引
- 文本索引:对字符串内容进行查询
- 一般在 字符串类型字段 或 字符串数组类型字段 上创建文本索引
- 使用文本索引查找时,不区分字母大小写
- 目前不支持中文文本索引,支持英语、法语、德语、俄语、西班牙语、土耳其语
- 文本索引具有 sparse 属性,忽略创建过程中的 sparse 选项
- 文本索引支持
$text 查询操作
- 限制
- 一个集合最多只能创建一个文档索引
- 排序操作 sort,不能使用文本索引中的排序
- 复合文本索引中,如果在文本索引键之前包含其他键,则通过 $text 搜索时,查询谓词必须包含前面键的相等匹配条件
- 只能通过索引名称删除文本索引
格式
db.collection.createIndex(
keys ,
options
)
-
keys
-
类型:Document
-
描述:text 类型的索引规范文档
-
单字段
{ field1: "text"}
-
多字段
{
field1: "text",
field2: "text",
...
}
// 复合索引
{
field1: 1,
field2: "text",
...
}
-
全部字段
用 $** 代表文档中的所有字符串类型的字段
{ "$**": "text" }
-
options
- weights
- 类型:Document
- 描述:
- 包含字段和权重的文档,指定字段的权重,默认值为1,可设定为 1-99999 之间的整数
- 优先查询权重大的字段,次之查询权重小的字段
- default_language
- 类型:字符串
- 描述
- 对于文本索引,不同的语言有不同的分析规则
- 默认值为
english
- language_override
- 类型:字符串
- 描述
- For text indexes, the name of the field, in the collection’s documents, that contains the override language for the document
- 默认值为
language
- textIndexVersion
示例
-
创建文本索引
db.reviews.createIndex( { comments: "text" } )
db.reviews.createIndex(
{
subject: "text",
comments: "text"
}
)
db.reviews.createIndex( { "$**": "text" } )
-
指定不同的权重
db.reviews.createIndex(
{ "$**": "text" } ,
{ weights : {subject: 10, comments: 5}}
)
Hashed 索引
格式
db.collection.createIndex( { field: "hashed" } )
索引属性
Unique 索引
Partial 索引
Sparse 索引
TTL 索引
-
生命周期性(文档在一段时间后会被mongodb自动删除)
-
一般在 Date类型的字段 或 包含Date类型元素的数组字段 上创建TTL索引,其他字段无效
-
过期阈值的计算
- 如果字段类型是 Date,则过期阈值是字段值日期加上指定的过期时间
- 如果字段类型是包含 Date 类型元素的数组,则过期阈值是元素中最早的日期加上指定的过期时间
- 如果非以上两种类型,TTL 索引无效,文档不会过期
-
将 expireAfterSeconds 设置为0,则过期时间就是日期字段的值
-
TTL 线程
- mongod 中的后台线程,每隔60秒运行一次,用来读取索引中的值并从集合中删除过期的文档
- 不保证文档过期后立即被删除,文档过期的时间和从数据库中删除的时间存在延迟(60s)
- 当 TTL 线程处于活动状态时,可以在
db.currentOp() 的输出中看到删除操作
-
限制
格式
db.collection.createIndex(
<keys>,
{
expireAfterSeconds: <integer>
}
)
示例
文档
db.ttl.insertMany([
{date:new Date("2020-08-13T17:50:00"), money:1},
{date:new Date("2020-08-13T17:52:00"), money:2},
{date:new Date("2020-08-13T17:54:00"), money:3},
])
db.ttl.createIndex({date:-1})
db.ttl.createIndex({date:1, money:-1})
db.ttl.createIndex({date:1},{expireAfterSeconds:10})
- 在 ttl 集合中的 date 字段上创建3个索引
- 有一个 TTL 索引,过期阈值为:date 日期加上指定过期时间
- 结果是,到过期阈值时,文档被依次删除
修改过期时间
db.runCommand({
collMod: <collection>,
index:{
keyPattern: <keys>,
expireAfterSeconds: <integer>
}
})
示例
db.ttl.insertMany([
{date:new Date("2020-08-13T18:08:00"), money:1},
{date:new Date("2020-08-13T18:09:00"), money:2},
{date:new Date("2020-08-13T18:10:00"), money:3},
])
db.runCommand({
collMod:"ttl",
index:{
keyPattern:{date:1},
expireAfterSeconds:60*60
}
})
返回结果
{ "expireAfterSeconds_old" : 10, "expireAfterSeconds_new" : 3600, "ok" : 1 }
Hidden 索引
4.4 新增
- 对查询规划器不可见,不能用于查询
- 用来评估删除索引的潜在影响,而不必实际删除该索引。如果影响是负面的,用户可以取消隐藏索引,而不必重新创建
- 索引在隐藏时也会被维护,因此一旦不隐藏,就可以立即使用这些索引
来源:https://www.cnblogs.com/usmile/p/13576813.html |