索引是資料庫設計中非常重要的一環,透過針對特定欄位(一個以上)建立索引,使得任何操作能夠快速找到資料,這也是為什麼操作的查詢條件通常都須建立索引的緣故,所以使用者情境(user scenario)對開發者來說非常重要,如果沒有這些情境,開發者無法預測這個功能該如何使用,進而無法設計出合適的結構或者索引等。
MongoDB 內的所有 collection 都有一個 Default Index,打開任一文件都會看到一個 _id
欄位,就是這個。
_id
不需要指定,寫入資料庫時就會自動幫你產生,當然你也可以自己客製化,在某些情境很適合。
MongoDB 索引欄位是有排序的,預設是正序1
,反序-1
則需要特別設定,至於要使用哪一種排序,需要根據你的使用情境來決定。
通常,跟時間相關都會查詢與現在較近的為主,例如最近一個月的營收、這週的進貨表等等,這樣就很適合使用反序來建立索引。
官方的文件載明,建議命名為 [欄位名稱1]_[排序]_[欄位名稱2]_[排序]
這樣的方式。
例如現在有兩個欄位分別叫 ProductId
使用正序,CreateTime
使用倒序,那以此建立的 index 會命名為ProductId_1_CreateTime_-1
。
127 bytes
顧名思義,使用一個欄位建立的 Index。
以下範例皆使用此 employee
的 collection (僅範例使用,沒考慮設計上問題)
{
"_id": ObjectId("60a7755055caee86c7479c96"),
"name": "Aaron",
"age": 30,
"department": 1,
"startWork": 2021-05-21T00:00:00.000+0800
"address": {
"city": "taipei",
"district": "east"
},
"assets": [
{"sn": "PC001", "name":"personal computer"},
{"sn": "OD001", "name": "office desk"}
]
},
{
"_id": ObjectId("60a7756955caee86c7479c97"),
"name": "Brad",
"age": 32,
"department": 2,
"startWork": 2021-04-21T00:00:00.000+0800,
"address": {
"city": "hsinchu",
"district": "south"
},
"assets": [
{"sn": "PC002", "name":"personal computer"},
{"sn": "OD002", "name": "office desk"}
]
}
針對 department 欄位建立索引:
db.employee.createIndex({"department": 1})
Index 也可以建立在 embedded field 上,使用 .
來做階層索引。以 city 為例:
db.employee.createIndex({"address.city": 1})
顧名思義是使用兩個以上的欄位組成的索引,在大部分情況都是使用這個的。以上面的範本為例:
db.employee.createIndex({"startWork": -1, "department" : 1})
Multikey index 是針對欄位是 array
使用的,使用方式如同一般 index 一樣,不需要額外指定它是 multikey。
db.employee.createIndex({"assets.sn" : 1})
文字索引,建立一個以上欄位的文字查詢索引。要特別注意的是一個collection只能有一個文字索引。
例如要針對 name
欄位建立文字索引,語法稍微不同,如下:
db.employee.createIndex({"name" : "text"})
查詢時不需指定欄位,需使用 $text
$search
語法。
單一字查詢:
db.employee.find({$text : {$search: "aaron"}}})
查詢多個字直接空白隔開即可,例如我要查詢包含 aaron asgard 的名字:
db.employee.find({$text : {$search: "aaron asgard"}}})
查詢包含空格的完整字串:
db.employee.find({$text : {$search: \""aaron asgard\""}}})
還有個反向的功能,例如要排除某一個字,可以使用 -
符號:
搜尋 aaron 但不包含 asgard
db.employee.find({$text : {$search: "aaron -asgard"}}})
看完後才發現忘記講如何取得索引,趕緊補上。
db.employee.getIndexes()
db.employee.dropIndex({"index_name"})
索引種類大致上介紹到這邊,明天繼續更深入的內容!
本系列文章會同步發表於我個人的部落格 Pie Note