你知道MongoDB的10種索引嗎?

爲何要有索引

查詢快! 查詢快! 查詢快!javascript

MongoDB的10種索引?

建立索引語法:css

db.<collection_name>.createIndex( <key and index type specification><options> )
複製代碼

咱們的record Collection存在以下documentjava

{
  "_id": ObjectId("570c04a4ad233577f97dc459"),
  "score"1034,
  "userId"123,
  "location": { state"ZH", city: "ChengDu" },
  "addr": [
    {zip: "10036", detail: "高家村五組"},
    {zip: "94231", detail: "王家鎮三組701"}
  ]
}
複製代碼

_id索引

mongodb會自動爲document中的_id字段加上索引,因此能用_id查詢就用_id查詢git

單鍵索引

db.records.createIndex( { score1 })
複製代碼

複合索引

db.records.createIndex( { userId1, score: 1})
複製代碼

多值索引

db.records.createIndex( { "addr.zip": 1 })
複製代碼

地理空間索引

MongoDB爲座標平面查詢提供了專門的索引,稱爲地理空間索引。這種查詢須要兩個維度,因此參數是2d。web

db.map.ensureIndex({"gps" : "2d"});
複製代碼

gps鍵的值必須是某種形式的一對值:一個包含2個元素的數組或者是包含2個鍵的內嵌文檔mongodb

{"gps" : [0,100]}
{"gps" : {"x" : -30 , "y" : 30}}
{"gps" : {"latitude" : -180"longitude" : 180 }}
複製代碼

至於鍵名能夠隨意。默認狀況下,地理空間索引假設值範圍是-180~180(對經緯度來講很方便),咱們一樣可使用參數來對索引進行定製,好比下面的星圖數據庫

db.star.trek.ensureIndex({"light-years" : "2d"} , {"min" : -1000, "max" : 1000, bits;10}, {collation: {locale: "simple"}});
複製代碼

上面的bits指定的是索引精度,默認狀況下2d index使用的是26位精度,在默認範圍-180~180中,大約等於60cm偏差,最大能夠設置32位精度。
索引精度不影響查詢精度,下降精度的優勢是插入操做的處理開銷較低,而且佔用的空間更少。較高精度的優勢是查詢掃描索引的較小部分以返回結果。apache

collation(排序規則)容許用戶爲字符串比較指定特定於語言的規則,例如字母和重音符號的規則。json

地理空間的查詢須要$near,它須要兩個目標值的數組做爲參數數組

db.map.find({"gps" : {"$near" : [40,-73]}}).limit(10);
複製代碼

默認查100個文檔,若是不須要這麼多,就應該設置一個少點的值以節約資源。

還可使用

db.runCommand({geoNear "map", near: [40,-73],num : 10})
複製代碼

geoNear的方式會返回每一個文檔到查詢點的距離。

還能夠查詢矩形和圓形內全部的點,這個時候就要將原來的$near換成$geoWithin .
對於矩形要使用$box選項,它的參數是2個元素的數組,第一個元素指定了左下角座標,第二個指定了右上角座標

db.map.find({"gps" : {"$geoWithin " : {"$box" : [[10,20],[15,30]]}}});
複製代碼

若是要查詢圓形,則要使用$center,參數變成了圓心和半徑

db.map.find({"gps" : {"$geoWithin " : {"$center" : [[12,25],5]}}});
複製代碼

地理空間查詢既可使用平面幾何,也可使用球面幾何,根據使用的查詢和索引類型來決定。 2dsphere 索引只能支持球面幾何,而 2d索引同時支持平面和球面幾何。
然而,在 2dsphere索引上使用球面幾何的查詢將會更高效和準確。

2dsphere : https://docs.mongodb.com/manual/core/2dsphere/

它的應用場景能夠是 查找附近美食,查找附近停車場等數據。

全文索引

建立索引:

db.<collection_name>.createIndex({<key>: "text"});
複製代碼

查詢數據:

db.<collection_name>.find( { $text: { $search"green" } } );
複製代碼

查詢以及排序:

db.<collection_name>.find(
{
 "$text": {
    "$search""green"
  }
},
{
  "textScore": {
    "$meta""textScore"
  }
}
).sort({
  "textScore": {
    "$meta""textScore"
  }
})
複製代碼

注意這裏的textScore並非集合中的某個字段,而是mongodb根據搜索結果計算該條數據的分數(匹配度預告,值越大)

TTL索引

我在以前的文章講到過這個索引,它其實是一個具備生命週期的索引,這種索引容許爲每個文檔設置一個超時時間。一個文檔達到預設置的老化程度後就會被刪除。

db.user_session.createIndex({"updated":1},{expireAfterSeconds:60*60*24});
複製代碼

若是一個文檔的updated字段存在而且它的值是日期類型,當服務器時間比文檔的updated字段的時間晚expireAfterSeconds秒時,文檔就會被刪除

db.getCollection('user_session').insert(
  {
    _id: NumberInt(1),
    "updated":new Date(),
     username:'lisi'
  }
);
複製代碼

部分索引

db.<collection_name>.createIndex(
{'wechat': 1 },
{
  "partialFilterExpression": {
    "wechat": {
      "$exists"true
    }
  }
}
)
複製代碼

上面的索引表示對存在wechat字段的文檔進行索引。部分索引僅索引集合中符合指定過濾器表達式的文檔,下降了索引建立和維護的性能成本。

部分索引提供了稀疏索引功能的超集,應優先於稀疏索引使用

稀疏索引

db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
複製代碼

索引不索引不包含xmpp_id字段的文檔。

哈希索引

db.collection.createIndex( { _id"hashed" })
複製代碼

哈希索引指按照某個字段的hash值來創建索引,目前主要用於MongoDB Sharded Cluster的Hash分片,hash索引只能知足字段徹底匹配的查詢,不能知足範圍查詢

後臺方式建立索引

db.<collection_name>.createIndex( <key and index type specification>, {background: true})
複製代碼

創建索引即耗時也費力,還須要消耗不少資源。使用{background: true}選項可使這個過程在後臺完成,同時正常處理請求。要是不包括這個選項,數據庫會阻塞創建索引期間的全部請求。
阻塞的作法會讓索引創建得更快,同時也意味着應用在此期間不能應答。即使後臺進行也會對正常操做有些影響,因此最好選在可有可無的時刻。後臺建立索引也會增長負載,好在不會讓服務器宕機。

不過從4.2版本開始,全部索引構建都使用優化的構建過程,該過程僅在構建過程的開始和結束時才持有排他鎖。其他的構建過程將產生交錯的讀寫操做。若是指定該屬性,MongoDB將忽略這個選項。

相關文章
相關標籤/搜索