MongoDB的索引(二)

太阳5个月前技术文章118


四、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" } }


相关文章

百万并发下的nginx优化

百万并发下的nginx优化

百万并发下的nginx优化之道一、nginx地址重写1、nginx地址重写(rewrite)介绍nginx地址重写的主要功能是实现URL地址的重定向。服务器获得一个来访的URL请求,然后改写成服务器可...

PG的多版本并发控制(一)

PG的多版本并发控制(一)

一、 表系统字段几个比较重要概念1.1  tupletuple表示表中的数据行,在MySQL中用row表示。在表数据页中,主要分为普通的数据元祖和TOAST元祖。以下是一个普通数据元祖的结构,主要由三...

ranger审计Solr部署

安装前准备1.1. 创建用户和用户组groupadd solruseradd -g solr solr1.2. 添加环境变量vi /etc/profile export SOLR_HOME=/opt/...

Linux命令traceroute—追踪网络路由利器

说明:通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径。当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能...

使用clickhouse-backup备份和恢复数据

使用clickhouse-backup备份和恢复数据

介绍clickhouse-backup是altinity提供的一个clickhouse数据库备份和恢复的工具,开源项目地址:https://github.com/Altinity/clickhouse...

Kubernetes源码解读(四)--Lister&Watcher源码分析

Kubernetes源码解读(四)--Lister&Watcher源码分析

Lister&&Watcher是Reflector的一个主要能力提供者,我们来看看Lister&&Watcher是如何实现List()和watch()的过程的。List...

发表评论    

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