MongoDB索引类型

索引类型

  • 单键索引
  • 组合索引 (几个字段一起)
  • 多值索引
  • 地理位置索引
  • 全文索引
  • TTL索引
  • 部分索引
  • 哈希索引

组合索引

db. members. find({ gender:"F", age:{$gte:18}}). sort("join_date":1)


组合索引的最佳方式:ESR原则
精确(Equal)匹配的字段放最前面
排序(Sort)条件放中间
范围(Range)匹配的字段放最后面

同样适用:ES,ER

{gender:1,age:1,join_date:1}
{gender:7,join_date:1,age:1}
{join_date:1,gender:1,age:1}
{join_date:1,age:1,gender:1}
{age:1,join_date:1,gender:1}
{age:1,gender:1,join_date:1}
这么多候选的,用哪一个?

按照  精确.排序.范围 的字段排序原则

{gender:7,join_date:1,age:1}  是最优的。

如果字段不满足这3个,只有两个或者更少,那么也要按照ESR的原则

组合索引工作模式
{a:1,b:2,c:1}
{a:1,b:2,c:2}
{a:2,b:2,c:1}
{a:2,b:2,c:3}
{a:2,b:3,c:1}
{a:2,b:3,c:2}
{a:2,b:3,c:4}

image-20220105135852096

db.test.createlndex({
	a:1,
	b:1,
	C:1
})
组合索引工作模式:精确匹配
# 创建索引
db.test.createIndex({a:1,b:1,c:1})

image-20220105140239743

db. test. find({
	a:2,
	b:2, 
	C:1
})

查找顺序: 先找到a2,再找到b2,再找到c1,这样就找到了数据页D所在的位置
组合索引工作模式:范围查询
# 创建索引
db.test.createIndex({a:1,b:1,c:1})

image-20220105140509756

db. test. find({
	a:2, 
	b:{$gte:2,$lte:3}, 
	C:1
})
范围组合查询:索引字段顺序的影响
db.test.find({
	a:2,
	b:{$gte:2,$lte:3},
	c:1
})

image-20220105140945748

创建索引的时候,遵循ESR原则,等值(E)一定要在最左侧,范围(R)在最右侧

范围+排序组合查询:索引字段顺序的影响
db.test.find({
	a:2,
	b:{$gte:2,$lte:3}).sort({c:1})

image-20220105210555508

地理位置索引

--创建索引
db.geo_col.createlndex(
	{location:“2d"},
	{min:-20,max:20,bits:10},
	{collation:{locale:"simple}}
)

--查询
db.geo_col.find(
	{location:
			{$geoWithin:	# 查询关键字
	{$box:[[1,1],[3,3]]}}}
)
--查询结果
{"id":Objectld("5c7e7a6243513eb45bf06125"),"location":[1,1]}
{"id":Objectld("5c7e7a6643513eb45bf06126"),"location":[1,2j}
{"id":Objectld("5c7e7a6943513eb45bf06127"),"location":[2,21}
{"id":Objectld("5c7e7a6d43513eb45bf06128"),"location":[2,1j}
{"id":Objectld("5c7e7a7343513eb45bf06129"),"location":[3,1]}
{"id":Objectld("5c7e7a7543513eb45bf0612a"),"location":[3,2]}
{"id":Objectld("5c7e7a7743513eb45bf0612b"),"location":[3,3j}

全文索引

--插入数据
db.<collection_name>.insert(
{id:1,content:"This morning I had a cup of coffee.",about:"beverage",keywords:[
“coffee"]},
{id:2,content:"Who doesn't like cake?",about:"food",keywords:["cake","food",
"dessert"]},
{id:3,content:"Why need coffee?",about:
"food",keywords:["drink","food"]}
)

--创建索引
>>db.<collection_name>.createlndex(
		{content':"text"}  				# 创建text index 全文索引
)




--查询  # 查询时,指定$text 关键字,使用全文索引查找
db.<collection_name>.find(
			{$text:			
						{$search:"cup coffee like"}
			})
db.<collection_name>.find(
			{$text:
						{$search:"a cup of coffee"}
			})

--查询排序
db.<collection_name>.find(
			{$text:{$search:"coffee"}},
			{textScore:{$meta:"textScore"}
).sort({textscore:{$meta:"textscore"})

部分索引

--创建部分索引
>>db.<collection_name>.createlndex(
		{a':1},
		{partialFilterExpression:
						{a:
							{$gte:5}
						}
)


# 建立部分索引关键字 partialFilterExpression
# 通过指定条件,a>=5 才会建立索引
--只对有wechat字段的建索引:
>>db.<collection_name>.createlndex(
		{wechat':1},
		{partialFilterExpression:
						{wechat:
							{$exists:true}
						}
)

# 也是通过partialFilterExpression 关键字过滤
# 只针对每条文档记录中存在wechat字段的 条目建立索引

image-20220105212327833

其他索引技巧

后台创建索引

# 使用 background ,在后台创建索引,占用更少的资源

db.member.createIndex({city:1},{background:true})

对BI/报表专用节点单独创建索引

  • 该从节点priority设为0
  • 关闭该从节点
  • 以单机模式启动
  • 添加索引(分析用)
  • 关闭该从节点,以副本集模式启动
posted @ 2022-05-19 23:41  oldSimon  阅读(144)  评论(0编辑  收藏  举报