MongoDB索引機(jī)制詳解
? MongoDB 的索引機(jī)制
與MySQL 一樣,"索引" 在 MongoDB 中也是用于優(yōu)化查詢的一種數(shù)據(jù)結(jié)構(gòu)。
通過創(chuàng)建適當(dāng)?shù)乃饕?,MongoDB 能夠快速地定位符合查詢條件的文檔,從而減少了掃描文檔的數(shù)量,提高了查詢性能。
? 索引的類型
MongoDB 的索引也是為了提升數(shù)據(jù)的檢索速度,原理也是先對(duì)數(shù)據(jù)進(jìn)行排序,然后就可以提升檢索的速度了。
因?yàn)槭?NoSQL 數(shù)據(jù)庫(kù),所以 MongoDB 存放記錄的數(shù)量要遠(yuǎn)超 MySQL ,如果沒有索引,一個(gè)查詢請(qǐng)求就會(huì)讓 MOngoDB 做全表掃描,這種檢索效率是非常低的。
一次查詢要花費(fèi)幾十秒甚至幾分鐘的時(shí)間,所以 “索引機(jī)制” 對(duì)于在海量數(shù)據(jù)中的快速定位查找就非常的重要了。
常用的索引有 "單字段索引"、"多字段索引"、"文本索引"、"空間索引" 等,接下來我們就來一一了解吧。
?? 創(chuàng)建索引 - 單字段索引
單字段索引是最簡(jiǎn)單的索引類型,它只包含一個(gè)字段。以前面章節(jié)中我們使用到的 “student” 集合 為例,可以在 name 字段上創(chuàng)建一個(gè)單字段索引。
單字段索引的創(chuàng)建語(yǔ)法:db.collection.createIndex({key:1},options);
- collection 為某一個(gè)集合;
- createIndex 為創(chuàng)建索引的函數(shù);
- key 為需要?jiǎng)?chuàng)建索引的字段, 1 表示升序排序,如果想要按照降序排序,可以使用 -1;索引可以加速對(duì) key 字段的查詢。
示例如下:
db.student.createIndex({name: 1 });
// 為集合 student 中 name 字段 創(chuàng)建索引,升序排列。

在創(chuàng)建索引的時(shí)候,經(jīng)常會(huì)使用的一些選項(xiàng)參數(shù),比如為索引命名、利用非阻塞模式等等,尤其是 “非阻塞模式”。在下文中的 “索引時(shí)的一些重要選項(xiàng)參數(shù)” 有詳細(xì)介紹。
?? 創(chuàng)建索引 - 多字段索引
多字段索引包含多個(gè)字段,用于加速涉及多個(gè)字段的查詢。
例如,在 students 集合中同時(shí)對(duì) "name" 和 "age" 字段創(chuàng)建一個(gè)多字段索引:
db.student.createIndex({name:1, age:-1});
// 為集合 student 中 name 字段 創(chuàng)建索引,升序排列, age 字段也創(chuàng)建索引,降序排列

上述代碼創(chuàng)建了一個(gè)名為 name_1_age_-1的多字段索引,其中的1和-1分別表示name字段和age 字段的排序規(guī)則。
?? 創(chuàng)建索引 - 唯一性索引
"唯一性索引" 用于確保一個(gè)集合中的文檔在指定字段上的值是唯一的。
唯一性索引只能創(chuàng)建在每個(gè)記錄都含有的公共字段上,在非公共字段上是不能創(chuàng)建唯一-性索引的。
在創(chuàng)建 “唯一性索引” 之后,MongoDB 會(huì)在索引中記錄每個(gè)文檔在該字段上的值,在插入或更新文檔時(shí),MongoDB 會(huì)比對(duì)索引中的值;
如果發(fā)現(xiàn)該字段上已經(jīng)存在同樣的值,就會(huì)拒絕寫入操作并拋出一個(gè)錯(cuò)誤。
在創(chuàng)建 “唯一性索引” 的時(shí)候,需要傳入 "unique 參數(shù)" 用于指定索引是否唯一。如果設(shè)置為 true,則在創(chuàng)建時(shí)將強(qiáng)制執(zhí)行該索引的唯一性約束。
以下是一個(gè)創(chuàng)建唯一索引的示例:
db.student.createIndex({"tel": 1},{ unique: true});
// 將集合 "student" 中 tel 字段設(shè)置為唯一索引

上述代碼將在 student 集合的 tel 字段上創(chuàng)建一個(gè)唯一性索引。在該索引中,每個(gè)文檔都對(duì)應(yīng)一個(gè)唯一的 tel 值。
需要注意的是,唯一性索引可能會(huì)影響 MongoDB 的性能,因?yàn)?MongoDB 需要在每個(gè)寫入操作中比較正在寫入的文檔與索引中的值。因此,在創(chuàng)建唯一性索引時(shí),需要根據(jù)需要選擇合適的字段,并避免過多的唯一性索引。
同時(shí),在操作唯一性索引時(shí),需要注意相關(guān)異常處理,例如捕獲索引操作拋出的錯(cuò)誤,以及避免在異常處理之前對(duì)集合進(jìn)行其他的寫入操作。
?? 創(chuàng)建索引 - 文本索引
文本索引也叫做全文索引,一般用于支持全文搜索。
通過在某些字段上創(chuàng)建文本索引,MongoDB 可以加速全文搜索操作,例如搜索文章中的一些關(guān)鍵字。
以下是一個(gè)使用文本索引實(shí)現(xiàn)全文搜索的示例:
db.articles.createIndex({content:"text"});
db.articles.find({$text:{ $search: "MongoDB is awesome"}});
上述代碼對(duì) articles 集合的 content 字段創(chuàng)建了一個(gè)文本索引,用于支持全文搜索。
查詢語(yǔ)句中,使用 $text 操作符指定使用全文索引,并傳遞了需要搜索的關(guān)鍵字 "MongoDB is awesome"。
?? 創(chuàng)建索引 - 地理空間索引
了解即可,反正我是沒用過。
在 MongoDB 中,地理空間索引用于支持地理位置(如經(jīng)度和緯度)的搜索和查詢。通過創(chuàng)建地理空間索引,MongoDB 可以快速地定位符合特定地理范圍內(nèi)的文檔。
在 MongoDB 中,有兩種類型的地理空間索引:2d 索引和2dsphere 索引。其中,2d 索引適用于操作平面上的地理位置信息,例如某個(gè)城市中的商鋪,而2dsphere 索引適用于操作三維空間中的地理位置信息,例如地球上的各個(gè)地理位置。
以下是一個(gè)在 stores 集合上創(chuàng)建 2dsphere 索引的示例:(示例是網(wǎng)上搜的)
db.stores.createIndex({ location: "2dsphere" });
上述代碼在 stores 集合的 location 字段上創(chuàng)建了一個(gè) 2dsphere 索引,以支持地理位置搜索。
下面是一個(gè)基于該索引的查詢示例:
db.stores.find({
location: {
$near: {
$geometry: {
type: "Point",
coordinates: [ -73.97, 40.77 ]
},
$maxDistance: 5000
}
}
});
在上述示例中,使用 $near 操作符和 $geometry 選項(xiàng)來定義將要搜索的坐標(biāo)點(diǎn) [ -73.97, 40.77 ],并使用 $maxDistance 選項(xiàng)來設(shè)置搜索的最大半徑為 5000 米。MongoDB 會(huì)使用 2dsphere 索引來快速地找到在這個(gè)范圍內(nèi)的文檔。
需要注意的是,在使用地理空間索引時(shí),需要注意索引的創(chuàng)建和使用方式,以及數(shù)據(jù)類型的正確性。同時(shí),也需要注意地理空間索引可能會(huì)帶來的性能開銷,并根據(jù)具體需求進(jìn)行索引的優(yōu)化和調(diào)整。
? 查看所有索引
當(dāng)我們創(chuàng)建了索引之后,可以通過 getIndexes() 函數(shù)可以獲取集合中所有索引。
查看索引語(yǔ)法示例:
db.student.getIndexes() // 查看集合 student 中的所有 "索引"

? 刪除索引
在 MongoDB 中,我們可以使用 dropIndex() 函數(shù)來刪除一個(gè)指定的索引,也可以使用 dropIndexes() 刪除一個(gè)集合上的所有索引。
**dropIndex() 函數(shù) ** 需要指定要?jiǎng)h除索引的集合名稱和索引的名稱或者參數(shù)。
例如,下面的代碼演示如何刪除名為 name_1 的索引:
db.student.dropIndex("name_1");
除了提供索引的名稱以外,還可以通過提供一個(gè)索引鍵或一個(gè)描述索引的選項(xiàng)對(duì)象來刪除特定的索引。
以下示例演示如何基于索引鍵刪除索引:
db.student.dropIndex({name_1: 1 });
在上述示例中,我們通過對(duì)象字面量傳遞一個(gè)索引鍵 { email: 1 },MongoDB 將會(huì)刪除關(guān)聯(lián)到該鍵的索引。
我們還可以使用 dropIndexes() 函數(shù) 來刪除一個(gè)集合上的所有索引。
以下是刪除所有索引的示例:
db.student.dropIndexes();

刪除索引之前需要確保是否真的需要?jiǎng)h除,因?yàn)樗饕怯糜诩铀俨樵兊?。同時(shí),還需要注意刪除索引所帶來的可能的性能問題。
如果刪除的索引是頻繁使用的索引,那么從索引中讀取文檔的性能會(huì)降低,因?yàn)?MongoDB 會(huì)像查詢數(shù)據(jù)庫(kù)時(shí)一樣執(zhí)行全文檢索。
所以,在刪除索引之前,需要對(duì)索引的使用情況做充分的評(píng)估。
? MongoDB 索引使用原則
MongoDB 索引的使用原則與 MySQL 是一致的:
- 數(shù)據(jù)量很大的集合必須創(chuàng)建索引,相反則不需要使用索引。
- 如果集合的數(shù)據(jù)讀取多過寫入,也是需要?jiǎng)?chuàng)建索引的,因?yàn)樗饕嵘氖虏樵兊乃俣?;如果?shù)據(jù)的寫入多過了數(shù)據(jù)的讀取,設(shè)置索引提升不了寫入的速度,反而會(huì)拖慢寫入的速度。因?yàn)閷懭胄碌臄?shù)據(jù)或者修改數(shù)據(jù)都會(huì)引發(fā)數(shù)據(jù)的排序,因此就會(huì)影響到寫入的速度。
- 并不是索引越多越好,那些經(jīng)常被用來當(dāng)做檢索條件的字段應(yīng)該設(shè)置索引,沒有被經(jīng)常當(dāng)做檢索條件的字段不需要設(shè)置索引。
以上就是MongoDB索引機(jī)制詳解的詳細(xì)內(nèi)容,更多關(guān)于MongoDB索引機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MongoDB批量將時(shí)間戳轉(zhuǎn)為通用日期格式示例代碼
這篇文章主要給大家介紹了關(guān)于MongoDB批量將時(shí)間戳轉(zhuǎn)為通用日期格式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MongoDB具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
MongoDB多數(shù)據(jù)源配置與切換的方法示例
這篇文章主要介紹了MongoDB多數(shù)據(jù)源配置與切換的方法示例,如何在SpringBoot應(yīng)用中配置并使用兩個(gè)MongoDB數(shù)據(jù)源,包括YAML配置文件的編寫,避免默認(rèn)MongoTemplate注入,文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07
基于?MongoTemplate實(shí)現(xiàn)MongoDB的復(fù)雜查詢功能
本文介紹了如何使用MongoTemplate進(jìn)行復(fù)雜的MongoDB查詢,展示了如何進(jìn)行分頁(yè)和排序查詢,通過示例代碼,展示了如何處理不同類型的查詢,如單條件查詢、模糊查詢、組合條件查詢以及分頁(yè)排序查詢,感興趣的朋友跟隨小編一起看看吧2024-12-12
MongoDB中多表關(guān)聯(lián)查詢($lookup)的深入講解
NoSql的多表關(guān)聯(lián)一直是比較復(fù)雜的問題,下面這篇文章主要給大家介紹了關(guān)于MongoDB中多表關(guān)聯(lián)查詢($lookup)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-12-12
MongoDB快速入門筆記(四)之MongoDB查詢文檔操作實(shí)例代碼
MongoDB 是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫(kù)。接下來通過本文給大家介紹MongoDB快速入門筆記(四)之MongoDB查詢文檔操作實(shí)例代碼,感興趣的朋友一起學(xué)習(xí)吧2016-06-06
MongoDB 索引創(chuàng)建和查詢優(yōu)化的方法
這篇文章主要介紹了MongoDB 索引創(chuàng)建和查詢優(yōu)化的方法,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-07-07

