MongoDB的索引(二)

太阳11个月前技术文章304


四、Case Insesitive索引

1、语法

db.collection.createIndex( 
{ "key" : 1 },
{ collation: {locale : <locale>,strength : <strength>}} )

collation:指定语言规则

strength:指定比较规则(是否区分大小写),1-5,数组越大,比较规则越严格,默认等级为3

2、使用case insensitive索引不影响查询结果,但是会增加查询的资源消耗

3、当创建索引时候指定了locale和strength,需要在查询时候指定相同的locale和strength才能确保有效使用索引。

1)示例集合

> db.fruit.find()
{ "_id" : ObjectId("5d2af3815e1bc81c62ef58b6"), "type" : "apple" }
{ "_id" : ObjectId("5d2af3815e1bc81c62ef58b7"), "type" : "Apple" }
{ "_id" : ObjectId("5d2af3815e1bc81c62ef58b8"), "type" : "APPLE" }
db.fruit.createIndex( { type: 1},
{ collation: { locale: 'en', strength: 2 } } )

2)查询结果

1.没有指定locale和strength,无法使用索引,查询记录为1
db.fruit.find( { type: "apple" } ) 

2.指定索引对应的locale和strength,使用索引,查询记录为2
db.fruit.find( { type: "apple" } ).collation( { locale: 'en', strength: 2 } )

3.指定非索引对应的locale和strength,不使用索引,返回记录为1
db.fruit.find( { type: "apple" } ).collation( { locale: 'en', strength: 1 } )

4、当创建集合时指定了locale和strength,集合的索引和查询默认使用对应的locale和strength。

1)示例集合

> db.createCollection("names", { collation: { locale: 'en_US', strength: 2 } } )
> db.names.createIndex( { first_name: 1 } ) // inherits the default collation
> db.names.find()
{ "_id" : ObjectId("5d3023b1cd8afaa592e2398d"), "first_name" : "Betsy" }
{ "_id" : ObjectId("5d3023b1cd8afaa592e2398e"), "first_name" : "BETSY" }
{ "_id" : ObjectId("5d3023b1cd8afaa592e2398f"), "first_name" : "betsy" }

2)查询结果

1.使用集合默认locale和strength,返回记录为3
db.names.find( { first_name: "betsy" } )

2.无法使用索引且只返回一条记录,因为strength默认为3
db.names.find( { first_name: "betsy" } ).collation( { locale: 'en_US' } )



五、Sparse索引

1、语法

db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )

2、稀疏索引的索引仅仅会覆盖包含索引字段的文档,所以根据稀疏索引来统计文档数/查询/排序时,可能得到的计算往往不是准确的

1)示例集合

> db.collection.find()
{ "_id" : 1, "y" : 1 }
{ "_id" : 2, "x" : 1, "y" : 2 }
{ "_id" : 3, "x" : 2 }

db.collection.createIndex( { x: 1 }, { sparse: true } );
db.collection.createIndex({ y: 1 });

2)查询结果

> db.collection.find().count();
3
> db.collection.find().hint({ y: 1 }).count();
3
> db.collection.find().hint( { x: 1 } ).count();        //仅统计x字段存在的记录
2

3、2dsphere (version 2)、 2d,、geoHaystack、text indexes都默认为稀疏索引

4、2dsphere和text都可以创建为稀疏复合索引,这些稀疏复合索引是否存在仅仅依赖于geospatial/text索引字段

5、稀疏索引的查询

1)示例文档

> db.scores.find()
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
> db.scores.createIndex( { score: 1 } , { sparse: true } )

2)查询结果

#查询结果不会包含无score字段记录
> db.scores.find( { score: { $lt: 90 } } )
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

6、稀疏索引的排序

1)示例文档

> db.scores.find()
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
> db.scores.createIndex( { score: 1 } , { sparse: true } )

2)查询结果

#COLLSCAN,未使用索引
> db.scores.find().sort( { score: -1 } )
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }

#强制使用稀疏索引后,得到记录只有2条
> db.scores.find().sort( { score: -1 } ).hint( { score: 1 } )
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

7、稀疏索引 + 唯一索引,仅仅限制满足稀疏索引字段唯一,不包含稀疏索引字段的文档可重复

1)示例集合

db.scores.createIndex( { score: 1 } , { sparse: true, unique: true } )
> db.scores.find()
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }

2)查询结果

> db.scores.insert( { "userid": "AAAAAAA", "score": 43 } )
WriteResult({ "nInserted" : 1 })
> db.scores.insert( { "userid": "BBBBBBB", "score": 34 } )
WriteResult({ "nInserted" : 1 })
> db.scores.insert( { "userid": "CCCCCCC" } )
WriteResult({ "nInserted" : 1 })
> db.scores.insert( { "userid": "DDDDDDD" } )
WriteResult({ "nInserted" : 1 })
>
> db.scores.insert( { "userid": "AAAAAAA", "score": 82 } )
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.scores index: score_1 dup key: { : 82.0 }"
}
})
> db.scores.insert( { "userid": "BBBBBBB", "score": 90 } )
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.scores index: score_1 dup key: { : 90.0 }"
}
})



六、Single Field Indexes

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

1、语法:

db.records.createIndex( { score: 1 } )

2、在嵌套字段上创建索引

db.records.createIndex( { "location.state": 1 } )

可支持查询:

db.records.find( { "location.state": "CA" } )
db.records.find( { "location.city": "Albany", "location.state": "NY" } )

3、在嵌套文档上创建索引

db.records.createIndex( { location: 1 } )

可支持查询:

db.records.find( { location: { city: "New York", state: "NY" } } )

需要注意的是:

对于以上查询,location嵌套字段的顺序与创建索引顺序不一致可以使用索引,但是查询结果记录为0,因为查询顺序

> db.records.find()
{ "_id" : ObjectId("570c04a4ad233577f97dc459"), "score" : 1034, "location" : { "state" : "NY", "city" : "New York" } }
>
> db.records.find( { location: { city: "New York", state: "NY" } } )
>
> db.records.find( { location: { state: "NY",city: "New York" } } )
{ "_id" : ObjectId("570c04a4ad233577f97dc459"), "score" : 1034, "location" : { "state" : "NY", "city" : "New York" } }


相关文章

借助arthas工具打火焰图

借助arthas工具打火焰图

1、下载arthas在命令行下面执行(使用和目标进程一致的用户启动,否则可能 attach 失败):curl -O https://arthas.aliyun.com/arthas-boot.jar...

lru_cache 缓存

Python 语法: @functools.lru_cache(maxsize=128, typed=False)Least-recently-used 装饰器。Iru 最近最少使用、cache 缓存...

Atlas集成HBase

Atlas集成HBase

1 集成原理 Atlas HBase hook与HBase master注册为协处理器。在检测到对HBase名称空间/表/列族的更改时, Atlas Hook过Kafka通知更新Atlas中的元数据。...

开源大数据集群部署(十五)Zookeeper集群部署

开源大数据集群部署(十五)Zookeeper集群部署

1、集群规划主机版本角色系统用户hd1.dtstack.com3.7.1followerzookeeperhd2.dtstack.com3.7.1leaderzookeeperhd3.dtstack....

开源大数据集群部署(五)Freeipa客户端部署及配置(kerberos+ldap)

开源大数据集群部署(五)Freeipa客户端部署及配置(kerberos+ldap)

1、安装IPA-Client安装(每个节点均需安装)yum install ipa-client -y2、执行安装命令ipa-client-install3、执行完成后进入交互阶段4、安装完成后查看页...

MySQL 复制-半同步搭建及原理

MySQL 复制-半同步搭建及原理

前言MySQL 半同步复制解决了什么问题?在传统主从架构中,主库实例提交事务与发送二进制日志是异步的,也就是说从库是否成功接收到二进制日志不会影响到主库事务提交,因此可能会出现  “主库发生宕机,主库...

发表评论    

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