MongoDB研究總結之索引部分
MongoDB是由C++語言所編寫的一種面向文檔的非關係型數據庫(是一種NoSql數據庫實現),也是介於關係型數據庫和非關係型數據庫之間的數據存儲產品,其提供了高性能、高可用、高可拓展及基於分佈式存儲的數據庫,是非關係型數據庫中功能最豐富,最類似關係型數據庫的一種集合、文檔格式的數據庫。
l 覆蓋查詢
l 高級索引
l 全文檢索
一、覆蓋查詢
在MongoDB中,當我們在一個或多個字段上建立索引之後,默認的索引字段會緩存到系統的RAM存儲中,如果我們使用find()查詢的字段爲索引字段的話,會直接從RAM中獲取索引字段,這就是覆蓋查詢原理,這時的速度遠比從數據庫文件中檢索文檔速度快,具體如下操作:
1、文檔準備
{
"_id" :ObjectId("57e89964b316d2e13cc0ba9b"),
"username" :"[email protected]",
"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:"[email protected]"},{nickname:1})
{"_id" : ObjectId("57e89964b316d2e13cc0ba9b"),"nickname" : "marky" }
B、已排除_id查詢
>db.user.find({username:"[email protected]"},{nickname:1,_id:0})
{"nickname" : "marky" }
有需要的話,可以使用explain來分析查詢的過程和結果。
最後,如果是以下的查詢,則不能使用覆蓋查詢:
l 索引字段全部是數組
l 索引字段全部是子文檔
二、高級索引
我們知道,在覆蓋查詢中不支持索引字段全部是數組或是子文檔中,但是我們依然可以針對這些字段建立索引,具體如下操作:
文檔準備:
{
"_id" :ObjectId("57e89964b316d2e13cc0ba9b"),
"username" :"[email protected]",
"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" :"[email protected]",
"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" :"[email protected]",
"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(新)討論,謝謝。