目录
MongoDB 的 索引管理(命令演示:常见索引类型(常规索引、文本索引、Hash索引);常见索引选项(索引名、唯一索引、局部索引、稀疏索引);创建、删除索引)
演示前提:
登录单机模式的 mongodb 服务器命令
mongod.exe --config "E:\install\mongodb\mongodb-4.2.25\mongod.conf"
登录【test】数据库的 mongodb 客户端命令
mongo mongodb://192.168.0.107:27017/test -u LJHAAA -p 123456
登录【admin】数据库的 mongodb 客户端命令
mongo mongodb://192.168.0.107:27017/admin -u admin -p 123456
索引介绍
与SQL数据库的索引类似,索引可提高查询效率。
如果没有索引,MongoDB必须扫描整个集合中所有文档,从而选择与查询语句匹配的文档。
如果存在合适的索引,MongoDB通过索引限制它必须检查的文档数量、快速定位要查询的文档。
索引会加速查询效率,但降低插入、删除文档(需要维护索引)的效率。
通常应该为经常需要查询的字段建立索引。
_id主键默认就有索引。这意味着你根据主键查询文档,效率总是很高。
创建索引的语法格式(MongoDB会保证只有当索引不存在时才会创建索引):
db.collection名.createIndex( <索引定义>, <选项> )
< 索引定义 > 的定义方式:
{字段名: 索引类型}
{字段1: 索引类型, 字段2, 索引类型}
下面介绍语法格式中的索引定义方式中的索引类型和选项
常见索引类型:
1、常规索引
常规索引:1或-1。 【@Indexed】
在 MongoDB 中,当使用 createIndex 方法创建索引时,可以通过指定 1 或 -1 来表示索引的排序顺序。
如果使用 1,表示按照字段值的 升序 进行索引排序。
如果使用 -1,表示按照字段值的 降序 进行索引排序
1-1、针对 【item】集合的【price】字段建立索引
创建命令
db.item.createIndex({price: 1})
// 在 MongoDB 中,当使用 createIndex 方法创建索引时,可以通过指定 1 或 -1 来表示索引的排序顺序。
// 如果使用 1,表示按照字段值的升序进行索引排序。
// 如果使用 -1,表示按照字段值的降序进行索引排序
// 使用 {price: 1} 表示为名为 price 的字段创建一个升序排序的索引。这将有助于优化查询并加快对 price 字段的排序操作
创建结果
如图:为 price 建立了索引
1-2、通过【price】字段查询
再通过【price】字段查询的时候,速度就会变快,因为会为这个字段建立索引。
查询命令
db.item.find({price: {$gt: 50}})
查询结果
现在数据量小,体现不出来。
但是有提示说用这个【price】字段查询的时候,将在查询辅助下进行,这个辅助就是指【price】索引。
2、文本索引
文本索引:“text”,用于支持对文本内容全文检索查询。 【@TextIndexed】
因为 MongoDB 直接使用 Lucene 作为全文检索的引擎,所以全文检索的效率很高。
2-1、为【comment】集合的 【body】字段创建文本索引
创建命令
对body创建文本索引,body就可支持全文检索。
db.comment.createIndex({body: "text"})
创建结果
2-2:、mongodb 全文检索默认不支持中文
演示命令
db.comment.find({$text: {$search: "评论"}})
// $text 表明要使用全文检索 , MongoDB默认不支持中文
// 如果要 mongodb 支持中文,需要自己去做一些扩展,增加一些分词器。
演示结果
如图,是有数据的,不过数据是中文,无法通过全文检索搜索出来。
因为 mongodb 的全文检索默认不支持中文。
2-3、使用英文内容演示全文检索
演示命令
db.comment.find({$text: {$search: "english"}})
// $text 表明要使用全文检索 , MongoDB默认不支持中文。
// 全文检索时有些是停用词,这些词不会建索引。
1、演示结果:全文检索成功
把要查询的【comment】集合的一些内容改成英文的。
如图,全文检索对检索英文的内容生效
2、演示结果:停用词
在全文搜索中,停用词(Stop Words)指的是那些被认为对搜索结果没有实质性贡献的常见词语或符号。这些停用词通常在建立全文索引时被忽略,以减少索引的大小并提高搜索性能
停用词通常包括像“and”、“or”、“but”等常见的连接词、代词和介词,因为它们在搜索过程中出现的频率很高,但往往对搜索结果的相关性并没有太大影响。通过排除这些停用词,可以减小索引的大小,加快搜索速度,并且使得搜索结果更加精确和相关。
在构建全文索引时,通常会预先定义一组停用词列表,这些词在索引构建过程中会被自动过滤掉,不会包含在索引中
如图:因为 【my】属于停用词,所以查不到数据。
3、Hash索引
Hash索引:“hashed”,Hash索引使用索引字段值的Hash表来维护索引条目。 【@HashIndexed】
hash 索引不支持全文检索,要做全文检索必须建立【text】索引
3-1、为【item】集合的【name】列创建Hash索引
创建hash索引的命令
为【item】集合的【name】列创建Hash索引
db.item.createIndex({name: "hashed"})
创建结果
3-2、查询【item】集合中【name】字段的值为【鼠标】的文档
查询命令
db.item.find({name: "鼠标"})
查询结果
常见索引选项:
name:指定索引名
演示为【item】集合中的【name】字段创建常规索引并指定索引名
db.item.createIndex({price: 1}, {name: "myindex"}) # 针对 price 建立索引,且指定索引名为myindex
// 1 表示为 name 列创建常规索引,
// {name: "myindex"} 表示指定索引名为 myindex
如图:显示的为索引指定索引名
unique:指定是否是唯一索引。
创建唯一索引后,该字段的值不允许重复。
演示:Hash索引不支持唯一索引
db.item.createIndex({name: "hashed"}, {unique: true})
// 1 表示为 name 列创建常规索引,
// {unique: true} 表示该索引是唯一的。
如图:Hash索引不支持唯一索引,因此该语句出错
演示:为【item】集合的【name】列创建常规索引,且该索引是唯一的。
db.item.createIndex({name: 1}, {unique: true}) 为name列创建常规索引,且该索引是唯一的。
如图:因为【item】集合的【name】字段的值有重复,所以创建不了唯一索引。
因为如果为一个字段创建唯一索引后,该字段的值不允许重复。
演示:为【books】集合的【name】列创建常规索引,且该索引是唯一的。
db.books.createIndex({name: 1}, {unique: true})
// 1 表示为 name 列创建常规索引,
// {unique: true} 表示该索引是唯一的。
如图:此时【books】集合中的【name】列没有重复值,可以为【name】列创建唯一索引。
如图,再插入一条重复的值,就会插入失败
partialFilterExpression:【局部索引】:只对集合中部分文档建立索引。
只有满足该选项所指定的表达式的文档才会被建立索引。
演示:在【item】集合中,只对price大于30的文档的price创建索引
db.item.createIndex({price: 1}, {partialFilterExpression: {price: {$gt: 30}}})
因此,如果你执行如下查询;
查询【price】大于 35 的文档,因为局部索引是对【price】大于 30 的文档创建,所以查询的文档都能在索引命中,所以查询速度就会比较快。
但这里数据太少,看不出效果
db.item.find({price: {$gt: 35}})
// 效率很高,你的查询条件在索引条件之内,因此只需要在索引后文档中查询。
查询【price】大于 15 的文档,因为局部索引是对【price】大于 30 的文档创建,所以查询的文档有些不能再索引里面命中,所以还是需要查询所有文档。
db.item.find({price: {$gt: 15}})
// 效率不行,你的查询条件不在索引条件之内,因此依然需要检索索引之外的文档。
sparse:将该属性指定为true表明建立稀疏索引,这意味着仅对索引字段存在的文档建立索引。
稀疏索引不会自动启用,只有在查询时使用hint(索引表达式)方法时才会启用稀疏索引
演示:对【books】集合中的【name】字段创建稀疏索引
稀疏索引——只有当文档存在name字段时,才会对该文档创建索引
db.books.createIndex({name:1}, {sparse: true})
// 对name创建稀疏索引——只有当文档存在name字段时,才会对该文档创建索引。
这里演示的时候,会把之前关于这个name的索引先删除掉。
如图:这个文档没有【name】这个字段,索引这个文档不会被建立【稀疏索引】
演示:启用稀疏索引进行查询:
db.books.find().hint({name:1})
// - 启用索引,只对索引后的文档进行检索。
// 虽然 find() 没有指定查询条件,但没有 name 字段的文档不是索引文档 ,因此无法检索得到
hint() 方法,它括号里面的 {name:1} 是索引表达式。
(我个人理解是对【name】这个字段进行稀疏索引查询)
通过使用 hint() 方法,可以显式地告诉 MongoDB 使用特定的索引执行查询,而不是让 MongoDB 自动选择索引。
如图:结合上面的演示:因为这个【price】= 110 的文档没有建立【稀疏索引】,所以在启用【稀疏索引】查询的时候,这个文档是不会被查询出来的
演示:不启用稀疏索引进行查询:
db.books.find(): 不启用稀疏索引。
如图:不启用【稀疏索引】查询的话,就所有数据都能查询出来。
通过命令来删除索引
命令格式:
db.collection名.dropIndex( 索引名 )
演示:用命令删除索引
db.books.dropIndex("price_1")
成功用命令删除索引