mongoDB学习笔记四

第五章 索引

>db.users.find({"username":"retacn yue"})

{ "_id" : ObjectId("586b40507dfc144b68de4071"),"relationships" : { "enemies" : 2, "friend" : 32}, "username" : "retacn yue", "age" : 33,"sex" : "ma

le", "location" :"ZiBo", "emails" : [ "zhenhuayue@hotmail.com","zhenhuayue@163.com", "zhenhuayue@soho.com", "zhenhuayue@126.com"], "state" : null,

"languages" : [ "java","python", "c", "c++" ] }

>db.users.ensureIndex({"username":1})

{

       "createdCollectionAutomatically" : false,

       "numIndexesBefore" : 1,

       "numIndexesAfter" : 2,

       "ok" : 1

}

扩展索引

创建索引需要考虑以下问题

1 作什么查询,哪些键要索引

2 索引方向

3 扩展中键的排列

 

 

索引内嵌文档中的键

> db.blog.posts.findOne()

{

       "_id" : ObjectId("586f21115da1e3bac2c373fe"),

       "title" : "A blog post",

       "content" : "...",

       "author" : {

                "name" : "retacnyue",

                "email" :"zhenhuayue@sina.com"

       },

       "comments" : [

                {

                        "name" :"yue",

                        "email" :"zhenhuayue@126.com",

                        "content" :"good",

                        "votes" : 11

                },

                {

                        "name" :"three",

                        "email" :"zhenhuayue@hotmail.com",

                        "content" :"better",

                        "votes" : 8

                },

                {

                        "name" :"zhenhua",

                        "email" :"zhenhuayue@qq.com",

                        "content" :"best",

                        "votes" : 11

                }

       ]

}

> db.users.ensureIndex({"author.name":1})

{

       "createdCollectionAutomatically" : false,

       "numIndexesBefore" : 2,

       "numIndexesAfter" : 3,

       "ok" : 1

}

 

为排序创建索引

无索引的排序,当集合大到不能在内存中排序,mongodb就会报错

 

索引名称

索引名形式:

Keyname1_dir1_keyname2_dir2_...keynameN_dirN

 

 

自定义索引名称

>db.users.ensureIndex({"location":1},{"location":"seq_location"})

{

       "createdCollectionAutomatically" : false,

       "numIndexesBefore" : 3,

       "numIndexesAfter" : 4,

       "ok" : 1

}

 

二唯一索引

确保文档中的username键都有一个唯一值,可以创建唯一索引

>db.users.ensureIndex({"age":1},{"unique":true})

{

       "createdCollectionAutomatically" : false,

       "numIndexesBefore" : 4,

       "numIndexesAfter" : 5,

       "ok" : 1

}

 

 

 

修改索引

#删除指定键的索引

> db.runCommand({"dropIndexes":"users","index":"username_1"})

{ "nIndexesWas" : 5,"ok" : 1 }

 

>db.runCommand({"dropIndexes":"users","index":"location_1"})

{ "nIndexesWas" : 4,"ok" : 1 }

 

#删除所有索引

>db.runCommand({"dropIndexes":"users","index":"*"})

{

       "nIndexesWas" : 3,

       "msg" : "non-_id indexes dropped for collection",

       "ok" : 1

}

 

消除重复

如果在创建索引前,数据库中已经有重复的键值,如果想要将重复的文档值全部删除,可以作如下操作

#添加用户名重复的键值

>db.users.insert({"username":"retacn yue"})

WriteResult({ "nInserted" : 1 })

 

#查询所有记录

> db.users.find()

{ "_id" :ObjectId("586b40507dfc144b68de4071"), "relationships" : {"enemies" : 2, "friend" : 32 }, "username" :"retacn yue", "age" : 33, "sex" : "ma

le", "location" :"ZiBo", "emails" : [ "zhenhuayue@hotmail.com","zhenhuayue@163.com", "zhenhuayue@soho.com","zhenhuayue@126.com" ], "state" : null,

"languages" : [ "java","python", "c", "c++" ] }

{ "_id" :ObjectId("58708a439193775a5f6b5f14"), "username" :"ann", "age" : 30, "sex" : "female","location" : "BoShan", "relationships" : {"enemies"

 : 1,"friend" : 20 }, "emails" : [ "znn@163.com","ann@sina.com" ], "state" : "T","languages" : [ "java", "python", "c++"] }

{ "_id" :ObjectId("58708aeb9193775a5f6b5f16"), "username" :"mike", "age" : 15, "sex" : "male","location" : "HuanTai", "relationships" : {"enemies"

 : 3,"friend" : 18 }, "emails" : [ "mike@163.com","mike@sina.com" ], "state" : "F","languages" : [ "java", "c++" ] }

{ "_id" :ObjectId("58708e5e9193775a5f6b5f18"), "username" :"andy", "age" : 18, "sex" : "female","location" : "ZhangDian", "relationships" : {"enem

ies" : 2, "friend" : 15 },"emails" : [ "andy@163.com", "andy@sina.com" ],"state" : "T", "languages" : [ "java","c", "c++" ] }

{ "_id" :ObjectId("5871d6cbc1be409ee45a7899"), "username" :"retacn yue" }

 

#这时创建唯一索引失败

>db.users.ensureIndex({"username":1},{"unique":true})

{

       "ok" : 0,

       "errmsg" : "E11000 duplicate key error collection:test.users index: username_1 dup key: { : \"retacn yue\" }",

       "code" : 11000

}

 

#如果想保留第一个文档,删除后面的重得文档,可以作如下操作

在mongodb在3.0后不建议使用

>db.users.ensureIndex({"username":1},{"unique":true,"dropDups":true})

 

复合唯一索引,单个健的值可以相同,只要键的组合不同就好

 

 

使用explain和hint

 

#会返回查询所使用的索引情况

#在建立索引前

>db.users.find({"username":"retacn yue"}).explain()

{

       "queryPlanner" : {

                "plannerVersion" : 1,

                "namespace" :"test.users",

                "indexFilterSet" :false,

                "parsedQuery" : {

                        "username" :{

                                "$eq": "retacn yue"

                       }

                },

                "winningPlan" : {

                        "stage" :"COLLSCAN",

                        "filter" : {

                               "username" : {

                                       "$eq" : "retacn yue"

                                }

                        },

                        "direction" :"forward"

                },

                "rejectedPlans" : [ ]

       },

       "serverInfo" : {

                "host" :"retacn",

               "port" : 27017,

                "version" :"3.2.11",

                "gitVersion" :"009580ad490190ba33d1c6253ebd8d91808923e4"

       },

       "ok" : 1

}

 

#在建立索引后

>db.users.find({"username":"retacn yue"}).explain()

{

       "queryPlanner" : {

                "plannerVersion" : 1,

                "namespace" :"test.users",

                "indexFilterSet" :false,

                "parsedQuery" : {

                        "username" :{

                                "$eq": "retacn yue"

                        }

                },

                "winningPlan" : {

                        "stage" :"FETCH",

                        "inputStage": {

                               "stage" : "IXSCAN",

                                "keyPattern": {

                                       "username" : 1

                                },

                               "indexName" : "username_1",

                               "isMultiKey" : false,

                               "isUnique" : false,

                               "isSparse" : false,

                               "isPartial" : false,

                               "indexVersion" : 1,

                               "direction" : "forward",

                                "indexBounds": {

                                       "username" : [

                                               "[\"retacn yue\", \"retacn yue\"]"

                                        ]

                                }

                        }

                },

                "rejectedPlans" : [ ]

       },

       "serverInfo" : {

                "host" :"retacn",

                "port" : 27017,

                "version" :"3.2.11",

                "gitVersion" :"009580ad490190ba33d1c6253ebd8d91808923e4"

       },

       "ok" : 1

}

 

 

 

四索引的管理

索引的元信息保存在system.indexes集合中,不能进行插入和删除文档的操作

可以使用ensureIndex和dropIndex进行

 

修改索引

#创建索引的工作在后台完成

>db.users.ensureIndex({"username":1},{"background":true})

{

       "createdCollectionAutomatically" : false,

       "numIndexesBefore" : 1,

       "numIndexesAfter" : 2,

       "ok" : 1

}

 

查看索引,删除索引

#查看当前数据库中建立的索引

> db.users.getIndexes()

[

       {

                "v" : 1,

                "key" : {

                        "_id" : 1

                },

                "name" :"_id_",

                "ns" :"test.users"

       },

       {

                "v" : 1,

                "key" : {

                        "username" :1

                },

                "name" :"username_1",

                "ns" :"test.users",

                "background" : true

       }

]

 

 

 

 

 

五地理空间索引

比如果查找离当前位置最近的n个场所,mongodb创建了专门的索引,地理空间索引

db.map.ensureIndex({“gps”:”2d”})

 

Gps的键值必须是一对值

{“gps”:{1,100}}

{“gps”:{“x”:20,”y”:30}}

 

也可以指定最大值,最小值

db.map.ensureIndex({“gps”:”2d”},{“min”:-100,”max”:100})

 

查询时可以使用$near

Db.map.find({“gps”:{“$near”:[10,20]}}).limit(10)

也可以使用geoNear来完成同上操作

db.runCommand({geoNear:”map”,near:[10,20],num:10})

 

 

 

也可以找到指定形状内的文档,box第一个元素指定了左下角的坐标,第二个元素指定右上角的坐标

Db.map.find({“gps”:{“$within”:{“$box”:[[10,20][15,30]]}}})

 

也可以用来查询圆内的所有点

Db.map.find({“gps”:{“$within’:{“$center”:[12,25],5}}})

 

 

复合地理空间索引

例如查询附近的咖啡店,可以将地理空间索引与普通索引组合起来

#创建索引

db.map.ensureIndex({“location”:”2d”,”desc”:1})

#查询

Db.map.find({“location”:{“$near”:[70,30]},”desc”:”coffeeshop”}).limit(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值