Mongodb基础入门(3)——排序和索引
今天继续Mongodb,简单的记录下其排序和索引的使用。
在Mongodb中使用sort()方法对数据进行排序。
命令格式:db.collectionName.find().sort({key:参数})
参数说明:
-1:表示降序
1:表示升序(默认)
doc集合中数据如下:
> db.doc.find({},{_id:0,goods_id:1})
{ "goods_id" : 1 }
{ "goods_id" : 4 }
{ "goods_id" : 3 }
{ "goods_id" : 5 }
{ "goods_id" : 6 }
{ "goods_id" : 7 }
{ "goods_id" : 8 }
{ "goods_id" : 9 }
{ "goods_id" : 10 }
{ "goods_id" : 11 }
{ "goods_id" : 12 }
> db.doc.find({},{_id:0,goods_id:1}).sort({goods_id:1})
索引
1、 简介
和mysql数据类似,为了提高查询效率,Mongodb也提供索引的支持。在Mongodb中,索引可以按照字段进行升序/降序来创建,以便于排序。当然,Mongodb默认采用B-tree方式来索引。
按索引作用类型可分为:
1、 单列索引:在单个键上创建索引。
2、 组合索引:在多个键上同时创建索引,也叫多列索引。
3、 文档索引:任何类型,包括文档(document)都可以作为索引。
索引的性质可以分:
1、 普通索引:普通方式创建的索引。注意:Mongodb存在默认的_id的键,相当于主键。集合在创建之后,系统会自动在_id创建索引,该索引为系统默认,无法删除。
2、 唯一索引:某列为唯一索引时,不能添加重复文档。注意,如果文档不存在指定字段时,会将该字段默认为null,而null也会被认为重复。
3、 稀疏索引:和稀疏矩阵类似,稀疏索引就是将含有某个字段的文档进行索引,不包含该字段的文档则进行索引。一般在小部分文档含有某列时常用。
4、 哈希索引:2.4版本新增的索引方式。相比于普通索引,其速度更快。但是无法对范围查询进行优化。多用于随机性比较强的散列当中。
2、 查看索引
db.collectionName.getIndexes()
3、 创建索引
A、 创建普通单列索引:默认是升序索引,采用B-tree方式
db.collectionName.ensureIndex({field:1/-1})//1:升序;-1:降序
B、 创建多列索引:
db.collectionName.ensureIndex({field1:1/-1,field2:1/-1})
C、 创建文档索引:
A)创建普通文档索引
db.collectionName.ensureIndex({filed:1/-1})
> db.users.insert({name:"god",info:{city:"NewYork",state:"happy"}})
WriteResult({"nInserted" : 1 })
>db.users.ensureIndex({info:1})//将整个info文档作为索引
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
>db.users.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.users"
},
{
"v" : 1,
"key" : {
"info" : 1
},
"name" : "info_1",
"ns" : "test.users"
}
]
注意:在使用索引查询的时候需要按照事先文档字段的顺序。
> db.users.find({info:{city:"NewYork",state:"happy"}})//能够利用索引查到结果
{ "_id" :ObjectId("54a79a1bc289fc3b6fcc719a"), "name" :"god", "info" : { "city
" : "NewYork", "state" : "happy" } }
>db.users.find({info:{$gte:{city:"New York"}}})//能够利用索引查到结果
{ "_id" :ObjectId("54a79a1bc289fc3b6fcc719a"), "name" :"god", "info" : { "city
" : "NewYork", "state" : "happy" } }
>db.users.find({info:{state:"happy",city:"New York"}})//不能利用索引查到结果
B)创建子文档索引
db.collectionName.ensureIndex({filed.subfield:1/-1})
> db.users.ensureIndex({"info.city":1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
>db.users.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.users"
},
{
"v" : 1,
"key" : {
"info.city" : 1
},
"name" : "info.city_1",
"ns" : "test.users"
}
]
D、创建唯一索引:可以针对多列创建唯一索引
db.collectinName.ensureIndex({filed.subfield:1/-1},{unique:true})
E、创建稀疏索引:
db.collectionName.ensureIndex({filed:1/-1},{sparse:true})
F、 创建哈希索引:可以对单个字段或字文档建立hash索引,不能针对多个列。
db.collectionName.ensureIndex({field:”hash”})
4、 删除索引
A、删除单个索引:
db.collectionName.dropIndex({filed:1/-1})
B、删除所有索引:_id列的索引不会删除。
db.collectionName.dropIndexes()
注意:在关系数据库中,表被删除后,索引随之删除。
而在Monodb中删除集合,索引仍然存在,因此需要手动删除索引。
5、 重建索引
一个集合在经过多次修改之后,将会导致集合的文件产生碎片。同样索引文件也会如此。因此可以通过索引的重建来减少索引文件碎片,提高索引效率。和mysql中的optimize table类似。命令:db.collectionName.reIndex().
索引的管理
1、查询所有索引:
system.indexes集合中包含了每个索引的详细信息,因此可以通过该命令:
db.system.indexes.find()查询已经存在的索引.
{"v" : 1, "key" : { "_id" : 1 }, "name": "_id_", "ns" : "test.doc" }
{"v" : 1, "key" : { "_id" : 1 }, "name": "_id_", "ns" : "test.category" }
{"v" : 1, "key" : { "_id" : 1 }, "name": "_id_", "ns" : "test.tea" }
{"v" : 1, "key" : { "email" : 1 },"name" : "sparse:1", "ns" : "test.tea"}
{"v" : 1, "key" : { "_id" : 1 }, "name": "_id_", "ns" : "test.users" }
{"v" : 1, "key" : { "info.city" : 1 },"name" : "info.city_1", "ns" :"test.users" }
2、查看查询计划:
为了分析查询性能及索引,一边获得更多查询方面有用的信息,可以使用如下命令:
db.collectionName.find(查询表达式).explain()
"cursor" :"BasicCursor" ——>表示索引没有发挥作用
"nscanned":1
——>表示查询了多少个文档。
"n",:1
——>表示返回的文档数量。
"millis":0 ——>表示整个查询的耗时。
"nscannedObjects" : 11, ——>理论上需要扫描多少行
3、后台创建索引
为已有数据的文档创建索引时,为了不阻塞其他操作,同时可以在后台创建索引,可以使用命令:db.test.ensureIndex({filed:1/-1},{"background":true})
相比阻塞创建索引而言,后台创建索引效率较低。
注意
1、如果数据集合比较小(一般来说是4m一下),此时如果使用sort()进行排序就不需要使用索引。
2、在使用组合索引查询时,查询字段的顺序必须和事先创建索引时的顺序保持一致。否则会出现上文提到的出现查不到的情况。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。