你知道MongoDB的10種索引嗎?

爲何要有索引

查詢快! 查詢快! 查詢快!git

MongoDB的10種索引?

建立索引語法:mongodb

db.<collection_name>.createIndex( <key and index type specification>, <options> )

咱們的record Collection存在以下document數據庫

{
  "_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查詢數組

單鍵索引

db.records.createIndex( { score: 1 })

複合索引

db.records.createIndex( { userId: 1, score: 1})

多值索引

db.records.createIndex( { "addr.zip": 1 })

地理空間索引

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

db.map.ensureIndex({"gps" : "2d"});

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

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

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

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

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

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

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

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/manu...

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

全文索引

建立索引:

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將忽略這個選項。

相關文章
相關標籤/搜索