這篇文章帶你了解MongoDB,介紹一下MongoDB中豐富的索引類型,希望對大家有幫助!
MongoDB
的索引和MySql
的索引的作用和最佳化要遵循的原則基本上相似,MySql
索引類型基本上可以區分為:
- 單鍵索引- 聯合索引
- 主鍵索引(叢集索引) - 非主鍵索引(非叢集索引)
在MongoDB
中除了這些基礎的分類之外,還有一些特殊的索引類型,如: 數組索引| 稀疏索引| 地理空間索引| TTL索引等.
為了下面方便測試我們使用腳本插入以下資料
for(var i = 0;i < 100000;i++){ db.users.insertOne({ username: "user"+i, age: Math.random() * 100, sex: i % 2, phone: 18468150001+i }); }
單鍵索引
單鍵索引即索引的欄位只有一個,是最基礎的索引方式.
在集合中使用username
欄位,建立單鍵索引,MongoDB
會自動將這個索引命名為username_1
db.users.createIndex({username:1}) 'username_1'
在建立索引後查看一下使用username
欄位的查詢計畫,stage
為IXSCAN
代表使用使用了索引掃描
db.users.find({username:"user40001"}).explain() { queryPlanner: { winningPlan: { ...... stage: 'FETCH', inputStage: { stage: 'IXSCAN', keyPattern: { username: 1 }, indexName: 'username_1', ...... } } rejectedPlans: [] , }, ...... ok: 1 }
在索引最佳化的原則當中,有很重要的原則就是索引要建立在基數高的的字段上,所謂基數就是一個字段上不重複數值的個數,即我們在創建users
集合時年齡出現的數值是0-99
那麼age
這個欄位將會有100個不重複的數值,即age
欄位的基數為100,而sex
這個欄位只會出現0 | 1
這個兩個值,即sex
欄位的基礎是2,這是一個相當低的基數,在這種情況下,索引的效率並不高並且會導致索引失效.
下面就船艦一個sex
字段索引,來查詢執行計劃會發現,查詢時是走的全表掃描,而沒有走相關索引.
db.users.createIndex({sex:1}) 'sex_1' db.users.find({sex:1}).explain() { queryPlanner: { ...... winningPlan: { stage: 'COLLSCAN', filter: { sex: { '$eq': 1 } }, direction: 'forward' }, rejectedPlans: [] }, ...... ok: 1 }
聯合索引
#即索引上會有多個欄位,下面使用age
和sex
兩個欄位建立一個索引
db.users.createIndex({age:1,sex:1}) 'age_1_sex_1'
然後我們使用這兩個欄位進行一次查詢,檢視執行計畫,順利地走了這條索引
db.users.find({age:23,sex:1}).explain() { queryPlanner: { ...... winningPlan: { stage: 'FETCH', inputStage: { stage: 'IXSCAN', keyPattern: { age: 1, sex: 1 }, indexName: 'age_1_sex_1', ....... indexBounds: { age: [ '[23, 23]' ], sex: [ '[1, 1]' ] } } }, rejectedPlans: [], }, ...... ok: 1 }
數組索引
數組索引就是對數組字段創建索引,也叫做多值索引,下面為了測試將users
集合中的資料增加一部分數組字段.
db.users.updateOne({username:"user1"},{$set:{hobby:["唱歌","篮球","rap"]}}) ......
建立陣列索引並進行檢視其執行計劃,注意isMultiKey: true
表示使用的索引是多值索引.
db.users.createIndex({hobby:1}) 'hobby_1' db.users.find({hobby:{$elemMatch:{$eq:"钓鱼"}}}).explain() { queryPlanner: { ...... winningPlan: { stage: 'FETCH', filter: { hobby: { '$elemMatch': { '$eq': '钓鱼' } } }, inputStage: { stage: 'IXSCAN', keyPattern: { hobby: 1 }, indexName: 'hobby_1', isMultiKey: true, multiKeyPaths: { hobby: [ 'hobby' ] }, ...... indexBounds: { hobby: [ '["钓鱼", "钓鱼"]' ] } } }, rejectedPlans: [] }, ...... ok: 1 }
陣列索引相比於其它索引來說索引條目和體積必然呈倍數增加,例如平均每個文檔的hobby
數組的size
為10,那麼這個集合的hobby
數組索引的條目數量將是普通索引的10倍.
聯合數組索引
聯合數組索引是含有數組字段的聯合索引,這種索引不支持一個索引中含有多個數組字段,即一個索引中最多能有一個數組字段,這是為了避免索引條目爆炸式增長,假設一個索引中有兩個數組字段,那麼這個索引條目的數量將是普通索引的n* m倍
地理空間索引
在原先的users
集合上,增加一些地理資訊
for(var i = 0;i < 100000;i++){ db.users.updateOne( {username:"user"+i}, { $set:{ location:{ type: "Point", coordinates: [100+Math.random() * 4,40+Math.random() * 3] } } }); }
建立一個二維空間索引
db.users.createIndex({location:"2dsphere"}) 'location_2dsphere' //查询500米内的人 db.users.find({ location:{ $near:{ $geometry:{type:"Point",coordinates:[102,41.5]}, $maxDistance:500 } } })
地理空間索引的type
有很多包含Ponit(點)
| LineString(線)
| Polygon (多邊形)
等
TTL索引
TTL的全拼法是time to live
,主要用於過期資料自動刪除,使用這種索引需要在文檔中聲明一個時間類型的字段,然後為這個字段創建TTL索引的時候還需要設置一個expireAfterSeconds
過期時間單位為秒,創建完成後MongoDB
會定期對集合中的資料進行檢查,當出現:
MongoDB
将会自动将这些文档删除,这种索引还有以下这些要求:
- TTL索引只能有一个字段,没有联合TTL索引
- TTL不能用于固定集合
- TTL索引是逐个遍历后,发现满足删除条件会使用
delete
函数删除,效率并不高
首先在我们文档上增减一个时间字段
for(var i = 90000;i < 100000;i++){ db.users.updateOne( {username:"user"+i}, { $set:{ createdDate:new Date() } }); }
创建一个TTL索引并且设定过期时间为60s,待过60s后查询,会发现这些数据已经不存在
db.users.createIndex({createdDate:1},{expireAfterSeconds:60}) 'createdDate_1'
另外还可以用CollMod
命令更改TTL索引的过期时间
db.runCommand({ collMod:"users", index:{ keyPattern:{createdDate:1}, expireAfterSeconds:120 } }) { expireAfterSeconds_old: 60, expireAfterSeconds_new: 120, ok: 1 }
条件索引
条件索引也叫部分索引(partial),只对满足条件的数据进行建立索引.
只对50岁以上的user
进行建立username_1
索引,查看执行计划会发现isPartial
这个字段会变成true
db.users.createIndex({username:1},{partialFilterExpression:{ age:{$gt:50} }}) 'username_1' db.users.find({$and:[{username:"user4"},{age:60}]}).explain() { queryPlanner: { ...... winningPlan: { stage: 'FETCH', filter: { age: { '$eq': 60 } }, inputStage: { stage: 'IXSCAN', keyPattern: { username: 1 }, indexName: 'username_1', ...... isPartial: true, ...... } }, rejectedPlans: [] }, ...... ok: 1 }
稀疏索引
一般的索引会根据某个字段为整个集合创建一个索引,即使某个文档不存这个字段,那么这个索引会把这个文档的这个字段当作null
建立在索引当中.
稀疏索引不会对文档中不存在的字段建立索引,如果这个字段存在但是为null
时,则会创建索引.
下面给users
集合中的部分数据创建稀疏索引
for(var i = 5000;i < 10000;i++){ if(i < 9000){ db.users.updateOne( {username:"user"+i}, { $set:{email:(120000000+i)+"@qq.email"}} ) }else{ db.users.updateOne( {username:"user"+i}, { $set:{email:null}} ) } }
当不建立索引使用{email:null}
条件进行查询时,我们会发现查出来的文档包含没有email
字段的文档
db.users.find({email:null}) { _id: ObjectId("61bdc01ba59136670f6536fd"), username: 'user0', age: 64.41483801726282, sex: 0, phone: 18468150001, location: { type: 'Point', coordinates: [ 101.42490900320335, 42.2576650823515 ] } } ......
然后对email
这个字段创建一个稀疏索引使用{email:null}
条件进行查询,则发现查询来的文档全部是email
字段存在且为null
的文档.
db.users.createIndex({email:1},{sparse:true}); 'email_1' db.users.find({email:null}).hint({email:1}) { _id: ObjectId("61bdc12ca59136670f655a25"), username: 'user9000', age: 94.18397576757012, sex: 0, phone: 18468159001, hobby: [ '钓鱼', '乒乓球' ], location: { type: 'Point', coordinates: [ 101.25903151863596, 41.38450145025062 ] }, email: null } ......
文本索引
文本索引将建立索引的文档字段先进行分词再进行检索,但是目前还不支持中文分词.
下面增加两个文本字段,创建一个联合文本索引
db.blog.insertMany([ {title:"hello world",content:"mongodb is the best database"}, {title:"index",content:"efficient data structure"} ]) //创建索引 db.blog.createIndex({title:"text",content:"text"}) 'title_text_content_text' //使用文本索引查询 db.blog.find({$text:{$search:"hello data"}}) { _id: ObjectId("61c092268c4037d17827d977"), title: 'index', content: 'efficient data structure' }, { _id: ObjectId("61c092268c4037d17827d976"), title: 'hello world', content: 'mongodb is the best database' }
唯一索引
唯一索引就是在建立索引地字段上不能出现重复元素,除了单字段唯一索引还有联合唯一索引以及数组唯一索引(即数组之间不能有元素交集 )
//对title字段创建唯一索引 db.blog.createIndex({title:1},{unique:true}) 'title_1' //插入一个已经存在的title值 db.blog.insertOne({title:"hello world",content:"mongodb is the best database"}) MongoServerError: E11000 duplicate key error collection: mock.blog index: title_1 dup key: { : "hello world" } //查看一下执行计划,isUnique为true db.blog.find({"title":"index"}).explain() { queryPlanner: { ...... winningPlan: { stage: 'FETCH', inputStage: { stage: 'IXSCAN', keyPattern: { title: 1 }, indexName: 'title_1', isMultiKey: false, multiKeyPaths: { title: [] }, isUnique: true, ...... } }, rejectedPlans: [] }, ....... ok: 1 }
相关视频教程推荐:《MongoDB教程》
以上是帶你聊聊MongoDB中豐富的索引類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

MongoDB适合处理大规模非结构化数据,Oracle适用于需要事务一致性的企业级应用。1.MongoDB提供灵活性和高性能,适合处理用户行为数据。2.Oracle以稳定性和强大功能著称,适用于金融系统。3.MongoDB使用文档模型,Oracle使用关系模型。4.MongoDB适合社交媒体应用,Oracle适合企业级应用。

MongoDB在擴展性和性能方面的考慮包括水平擴展、垂直擴展和性能優化。 1.水平擴展通過分片技術實現,提高系統容量。 2.垂直擴展通過增加硬件資源提升性能。 3.性能優化通過合理設計索引和優化查詢策略實現。

MongoDB是一種NoSQL數據庫,因其靈活性和可擴展性在現代數據管理中非常重要。它採用文檔存儲,適合處理大規模、多變的數據,並提供強大的查詢和索引能力。

MongoDB 中批量刪除文檔可以使用以下方法:1. $in 操作符指定要刪除的文檔列表;2. 正則表達式匹配符合條件的文檔;3. $exists 操作符刪除具有指定字段的文檔;4. find() 和 remove() 方法先獲取再刪除文檔。請注意,這些操作無法使用事務,並可能刪除所有匹配的文檔,因此使用時需謹慎。

要設置MongoDB數據庫,可以使用命令行(use和db.createCollection())或mongo Shell(mongo、use和db.createCollection())。其他設置選項包括查看數據庫(show dbs)、查看集合(show collections)、刪除數據庫(db.dropDatabase())、刪除集合(db.<collection_name>.drop())、插入文檔(db.<collecti

部署 MongoDB 集群分五步:部署主節點,部署輔助節點,添加輔助節點,配置複製,驗證集群。包括安裝 MongoDB 軟件、創建數據目錄、啟動 MongoDB 實例、初始化複製集、添加輔助節點、啟用副本集功能、配置投票權,並驗證集群狀態和數據複製。

MongoDB 廣泛應用於以下場景:文檔存儲:管理用戶資料、內容、產品目錄等結構化和非結構化數據。實時分析:快速查詢和分析日誌、監控儀錶盤展示等實時數據。社交媒體:管理用戶關係圖譜、活動流和消息傳遞。物聯網:處理設備監控、數據收集和遠程管理等海量時間序列數據。移動應用:作為後端數據庫,同步移動設備數據、提供離線存儲等。其他領域:電子商務、醫療保健、金融服務和遊戲開發等多樣化場景。

如何查看 MongoDB 版本:命令行:使用 db.version() 命令。編程語言驅動程序:Python:print(client.server_info()["version"])Node.js:db.command({ version: 1 }, (err, result) => { console.log(result.version); });


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Dreamweaver Mac版
視覺化網頁開發工具

記事本++7.3.1
好用且免費的程式碼編輯器