MongoDB研究总结之索引部分

来源:互联网 发布:ubuntu 16.04装软件 编辑:程序博客网 时间:2024/06/15 07:41

MongoDB研究总结之索引部分

 

MongoDB是由C++语言所编写的一种面向文档的非关系型数据库(是一种NoSql数据库实现),也是介于关系型数据库和非关系型数据库之间的数据存储产品,其提供了高性能、高可用、高可拓展及基于分布式存储的数据库,是非关系型数据库中功能最丰富,最类似关系型数据库的一种集合、文档格式的数据库。

 

l   覆盖查询

l   高级索引

l   全文检索

 

一、覆盖查询

在MongoDB中,当我们在一个或多个字段上建立索引之后,默认的索引字段会缓存到系统的RAM存储中,如果我们使用find()查询的字段为索引字段的话,会直接从RAM中获取索引字段,这就是覆盖查询原理,这时的速度远比从数据库文件中检索文档速度快,具体如下操作:

 

1、文档准备

{

     "_id" :ObjectId("57e89964b316d2e13cc0ba9b"),

     "username" :"marky@123.com",

     "nickname" : "marky",

     "address" : "云端路1024号,柯南私募基金大厦",

     "contact" :"13141250012",

     "created" : "2012-07-08",

     "orders" : [

         ObjectId("57e89b3ab316d2e13cc0ba9c"),

         ObjectId("57e89bcfb316d2e13cc0ba9d")

     ],

     "avaliable" : 0

}

 

2、建立索引

我们在上面的文档中,以字段username和nickname建立默认索引:

>db.user.ensureIndex({username:1,nickname:1})

{

     "createdCollectionAutomatically": false,

     "numIndexesBefore" : 1,

     "numIndexesAfter" : 2,

     "ok" : 1

}

 

3、查询集合

A、未排除_id查询

>db.user.find({username:"marky@123.com"},{nickname:1})

{"_id" : ObjectId("57e89964b316d2e13cc0ba9b"),"nickname" : "marky" }

 

 

B、已排除_id查询

>db.user.find({username:"marky@123.com"},{nickname:1,_id:0})

{"nickname" : "marky" }

 

有需要的话,可以使用explain来分析查询的过程和结果。

 

最后,如果是以下的查询,则不能使用覆盖查询:

l   索引字段全部是数组

l   索引字段全部是子文档

 

二、高级索引

我们知道,在覆盖查询中不支持索引字段全部是数组或是子文档中,但是我们依然可以针对这些字段建立索引,具体如下操作:

 

文档准备:

{

     "_id" :ObjectId("57e89964b316d2e13cc0ba9b"),

     "username" :"marky@123.com",

     "nickname" : "marky",

     "address" : {

         "city" : "中国上海",

         "street" : "云端路1024号,柯南私募基金大厦",

         "postcode" :"114300"

     },

     "contact" :"13141250012",

     "created" :"2012-07-08",

     "orders" : [

         ObjectId("57e89b3ab316d2e13cc0ba9c"),

          ObjectId("57e89bcfb316d2e13cc0ba9d")

     ],

     "avaliable" : 0

}

 

1、数组索引

建立索引:

>db.user.ensureIndex({"orders":1})

{

     "createdCollectionAutomatically": false,

     "numIndexesBefore" : 2,

     "numIndexesAfter" : 3,

     "ok" : 1

}

 

检索查询:

>db.user.find({orders:ObjectId("57e89b3ab316d2e13cc0ba9c")}).pretty()

{

     "_id" :ObjectId("57e89964b316d2e13cc0ba9b"),

     "username" :"marky@123.com",

     "nickname" : "marky",

     "address" : {

         "city" : "中国上海",

         "street" : "云端路1024号,柯南私募基金大厦",

         "postcode" :"114300"

     },

     "contact" : "13141250012",

     "created" :"2012-07-08",

     "orders" : [

         ObjectId("57e89b3ab316d2e13cc0ba9c"),

         ObjectId("57e89bcfb316d2e13cc0ba9d")

     ],

     "avaliable" : 0

}

 

结果分析:

>db.user.find({orders:ObjectId("57e89b3ab316d2e13cc0ba9c")}).explain()

 

 

2、子文档索引

建立索引:

>db.user.ensureIndex({'address.city':1,'address.street':1,'address.postcode':1})

{

     "createdCollectionAutomatically": false,

     "numIndexesBefore" : 3,

     "numIndexesAfter" : 4,

     "ok" : 1

}

 

检索查询:

>db.user.find({"address.postcode":"114300"}).pretty()

{

     "_id" : ObjectId("57e89964b316d2e13cc0ba9b"),

     "username" :"marky@123.com",

     "nickname" : "marky",

     "address" : {

         "city" : "中国上海",

         "street" : "云端路1024号,柯南私募基金大厦",

         "postcode" :"114300"

     },

     "contact" :"13141250012",

     "created" :"2012-07-08",

     "orders" : [

          ObjectId("57e89b3ab316d2e13cc0ba9c"),

         ObjectId("57e89bcfb316d2e13cc0ba9d")

     ],

     "avaliable" : 0

}

 

需要注意的是查询的表达式字段顺序,必须和创建索引时一致哦!

 

结果分析:

> db.user.find({'address.city':

'中国上海',"address.postcode":"114300"}).explain()

 

 

三、全文检索

全文检索对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式,类似于通过字典中的检索字表查字的过程(注:暂不支持中文)。

 

1、启用全文检索

MongoDB2.6之后默认支持开启全文检索,若是以前的版本,则需要如下操作,开启全文检索的支持,具体如下:

>db.adminCommand({setParameter:true,textSearchEnabled:true})

或者

$sudo./mongod  --setPatameter textSearchEnabled=true

 

2、创建全文检索

文档准备:

{

     "_id" :ObjectId("57f363f4e7e4ca0b4b610d80"),

     "title" : "MongoDB HighDesigning",

     "text" : "this book is verygood,you can study form it more!"

}

 

建立索引:

>db.book.ensureIndex({text:"text"})

{

     "createdCollectionAutomatically": false,

     "numIndexesBefore" : 1,

     "numIndexesAfter" : 2,

     "ok" : 1

}

 

3、使用全文检索

我们已经对text建立了全文索引,所以可以搜索text字段中的关键词了,具体如下操作:

>db.book.find({$text:{$search:"Java"}}).pretty()

{

     "_id" :ObjectId("57f36444e7e4ca0b4b610d81"),

     "title" : "Java HighDesigning",

     "text" : "the book that youcan study form it,how use the java lanague!"

}

 

>db.book.find({$text:{$search:"book"}}).pretty()

{

     "_id" :ObjectId("57f36444e7e4ca0b4b610d81"),

     "title" : "Java HighDesigning",

     "text" : "the book that youcan study form it,how use the java lanague!"

}

{

     "_id" : ObjectId("57f36459e7e4ca0b4b610d82"),

     "title" : "PHP HighDesigning",

     "text" : "the book that youcan study form it,how use the php lanague!"

}

{

     "_id" :ObjectId("57f363f4e7e4ca0b4b610d80"),

     "title" : "MongoDB HighDesigning",

     "text" : "this book is verygood,you can study form it more!"

}

 

注意:

如果是旧版的MongoDB实例,需要使用如下命令:

>db.book.runCommand(“text”,{search:”book”})

 

4、删除全文检索

删除已经存在的索引,我们可以先查询出索引名字:

>db.book.getIndexes()

[

     {

         "v" : 1,

         "key" : {

              "_id" : 1

         },

         "name" : "_id_",

         "ns" : "mydb.book"

     },

     {

         "v" : 1,

         "key" : {

              "_fts" :"text",

              "_ftsx" : 1

         },

         "name" :"text_text",

         "ns" : "mydb.book",

         "weights" : {

              "text" : 1

         },

         "default_language" :"english",

         "language_override" :"language",

         "textIndexVersion" : 3

     }

]

 

通过上面的命令,我们得到了索引名字为text_text,那么执行如下命令:

>db.book.dropIndex("text_text")

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

 

删除索引之后,我们再行查看下索引是否存在:

>db.book.getIndexes()

[

     {

         "v" : 1,

         "key" : {

              "_id" : 1

         },

         "name" : "_id_",

         "ns" : "mydb.book"

     }

]

> 

 

上面的结果说明,索引已经不存在了。

 

 

 

 

 

好了,Mongodb研究总结之索引部分就介绍到这里,由于作者水平有限,如有问题请在评论发言或是QQ群276592700(新)讨论,谢谢。

 

 

 

 

 

1 0
原创粉丝点击