MongoDB的索引(三)

太阳5个月前技术文章110

七、Compound Indexes

{
 "item": "Banana",
 "category": ["food", "produce", "grocery"],
 "location": "4th Street Store",
 "stock": 4,
 "type": "cases"
}

1、语法

db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )

2、复合索引中包含的一些隐式索引

{a:1,b:1,c:1} <=> {a:1}
              <=> {a:1,b:1}
              <=> {a:1,b:1,c:1}

3、利用索引进行排序

示例:db.data.createIndex( { a:1, b: 1, c: 1, d: 1 } )


语句

使用索引

db.data.find().sort( { a: 1 } )

{ a: 1 }

db.data.find().sort( { a: -1 } )

{ a: 1 }

db.data.find().sort( { a: 1, b: 1 } )

{ a: 1, b: 1 }

db.data.find().sort( { a: -1, b: -1 } )

{ a: 1, b: 1 }

db.data.find().sort( { a: 1, b: 1, c: 1 } )

{ a: 1, b: 1, c: 1 }

db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } )

{ a: 1, b: 1 }

db.data.find( { a: 5 } ).sort( { b: 1, c: 1 } )

{ a: 1 , b: 1, c: 1 }

db.data.find( { b: 3, a: 4 } ).sort( { c: 1 } )

{ a: 1, b: 1, c: 1 }

db.data.find( { a: 5, b: { $lt: 3} } ).sort( { b: 1 } )

{ a: 1, b: 1 }


八、Multikey indexes

1、在数组上创建索引时,MongoDB会自动为该集合创建multikey索引。

2、由于multikey indexes会对数组中每个值做索引,所以如果该字段设置为unique multikey indexes,那需要保证该集合中index数组不能重复

1)示例集合

> db.cc.find()
{ "_id" : 6, "type" : "food", "item" : "bbb", "ratings" : [ 5, 9 ] }
> db.cc.createIndex({ratings:1},{unique:true})

2)查询结果

> db.cc.insert({"_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 1,2 ]})
WriteResult({ "nInserted" : 1 })
>
> db.cc.insert({"type" : "food", "item" : "aaa", "ratings" : [ 7,3 ]})
WriteResult({ "nInserted" : 1 })
>
> db.cc.insert({"type" : "food", "item" : "aaa", "ratings" : [ 7,4 ]})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.cc index: ratings_1 dup key: { : 7.0 }"
}
})
> db.cc.insert({"type" : "food", "item" : "aaa", "ratings" : [ 6,9 ]})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.cc index: ratings_1 dup key: { : 9.0 }"
}
})
> db.cc.insert({"type" : "food", "item" : "aaa", "ratings" : [ 6,8 ]})
WriteResult({ "nInserted" : 1 })
>
>
> db.cc.find()
{ "_id" : 6, "type" : "food", "item" : "bbb", "ratings" : [ 5, 9 ] }
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 1, 2 ] }
{ "_id" : ObjectId("5d2e7c6dc5002cd792e912a9"), "type" : "food", "item" : "aaa", "ratings" : [ 7, 3 ] }
{ "_id" : ObjectId("5d2e7c8ac5002cd792e912ae"), "type" : "food", "item" : "aaa", "ratings" : [ 6, 8 ] }

2、multikey indexes的一些限制

{ _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 ] }

1)不能同时在两个数组字段建立复合multikey indexes

2)由于MongoDB3.6版本对排序行为上做了一些改变,导致现在对multikey index进行排序时,查询计划包括一个阻塞排序的阶段,从而对性能产生影响。在排序阻塞阶段,必须等待所有输入完成才能进行排序然后输出结果;对于一个非阻塞排序或者索引排序,sort操作只需要扫描index产生一个有序的请求。

3)multikey indexes不能做分片键,但是,如果一个分片是复合索引的前缀,这个复合索引支持nultikey index。

4)hash索引不支持multikey index

5)multikey index不支持覆盖索引查询

6)multikey index无法使用$expr

3、db.inventory.find( { ratings: [ 5, 9 ] } ),对于该multikey index的查询,MongoDB通过索引查找出所有包含5的记录,然后过滤出[5,9]的记录

4、Multikey Index Bounds

db.survey.insertMany([
{ _id: 1, item: "ABC", ratings: [ 2, 9 ] },
{ _id: 2, item: "XYZ", ratings: [ 4, 3 ] }])

db.survey.createIndex( { ratings: 1 } )

1)Intersect Bounds

db.survey.find( { ratings : { $elemMatch: { $gte: 3, $lte: 6 } } } )
<=>     ratings: [ [ 3, 6 ] ]
执行计划:
"indexBounds" : {
"ratings" : [
"[3.0, 6.0]"
]
}

2)不使用 $elemMatch的情况下MongoDB不会使用multikey inedex的交集

db.survey.find( { ratings : { $gte: 3, $lte: 6 } } )
<=>     ratings: [ [ 3, Infinity ] ] or [ [ -Infinity, 6 ] ]
执行计划:
"indexBounds" : {
"ratings" : [
"[-inf.0, 6.0]"
]
}

3)Compound Bounds - 等值查询

db.survey.find( { item: "XYZ", ratings: { $gte: 3 } } )
db.survey.createIndex( { item: 1, ratings: 1 } )
<=>     ratings: { item: [ [ "XYZ", "XYZ" ] ], ratings: [ [ 3, Infinity ] ] }
执行计划:
"indexBounds" : {
"item" : [
"[\"XYZ\", \"XYZ\"]"
],
"ratings" : [
"[3.0, inf.0]"
]
}

4)Compound Bounds - 范围查询

db.survey.find( {item: { $gte: "L", $lte: "Z"}, ratings : { $elemMatch: { $gte: 3, $lte: 6 } }} )
<=>     ratings: "item" : [ [ "L", "Z" ] ], "ratings" : [ [3.0, 6.0] ]
执行计划:
"indexBounds" : {
"item" : [
"[\"L\", \"Z\"]"
],
"ratings" : [
"[3.0, 6.0]"
]
}

5)Compound Bounds -

1.示例集合

> db.survey.insertMany([{ _id: 1, item: { name: "ABC", manufactured: 2016 }, ratings: [ 2, 9 ] }, 
{ _id: 2, item: { name: "XYZ", manufactured: 2013 },  ratings: [ 4, 3 ] }])
>
> db.survey.createIndex( { "item.name": 1, "item.manufactured": 1, ratings: 1 } )

2.查询结果

> db.survey.find( {    "item.name": "L" ,    "item.manufactured": 2012 } )
<=>     "item.name" : [ ["L", "L"] ], "item.manufactured" : [ [2012.0, 2012.0] ]
执行计划:
"indexBounds" : {
"item.name" : [
"[\"L\", \"L\"]"
],
"item.manufactured" : [
"[2012.0, 2012.0]"
],
"ratings" : [
"[MinKey, MaxKey]"
]
}


相关文章

docker安装及常用操作

docker安装及常用操作

一、安装docker1、移除以前docker相关包sudo yum remove docker \      ...

Kubernetes安全--securityContext介绍

securityContext是用来控制容器内的用户权限,你想用什么用户去执行程序或者执行操作等等。1. securityContext介绍安全上下文(Security Context)定义 Pod...

helm简介

helm简介

一、Helm 是什么在没使用 helm 之前,向 kubernetes 部署应用,我们要依次部署 deployment、svc 等,步骤较繁琐。况且随着很多项目微服务化,复杂的应用在容器中部署以及管理...

doris数据删除恢复

用户执行命令drop database/table/partition之后,再使用命令recover来恢复整个数据库/表/分区的所有数据。这种修复将会把FE上的数据库/表/分区的结构,从catalog...

Ldap高可用部署

Ldap配置高可用两个节点上均执行mkdir /data/ldapcd /data/ldap1.1. 添加mod_syncprov.ldif文件vi mod_syncprov.ldif 内容如下:ob...

慢查询导致ES CPU资源打满

慢查询导致ES CPU资源打满

o   一、问题背景§  1.1 集群背景信息§  1.2 收到告警o   二、处理过程§  2.1 查看监控§  2.2 登录kibana查看§  2.3 登录服务器使用命令查看·       2....

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。