'淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題'

MongoDB 數據庫 人生第一份工作 數據結構 JAVA架構師之路 2019-08-07
"
"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

第二步:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

第二步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

數據過期類型:

  • 當指定時間到了過期的閾值數據就會過期並刪除;
  • 如果字段是數組,並且索引中有多個日期值,MongoDB使用數組中最低(即最早)的日期值來計算到期閾值;
  • 如果文檔(document)中的索引字段不是日期或包含日期值的數組,則文檔(document)將不會過期;
  • 如果文檔(document)不包含索引字段,則文檔(document)不會過期。

TTL索引特有限制:

  • TTL索引是單字段索引。 複合索引不支持TTL並忽略expireAfterSeconds選項;
  • _id屬性不支持TTL索引;
  • 無法在上限集合上創建TTL索引,因為MongoDB無法從上限集合中刪除文檔;
  • 不能使用createIndex()方法來更改現有索引的expireAfterSeconds值。而是將collMod數據庫命令與索引集合標誌結合使用。 否則,要更改現有索引的選項的值,必須先刪除索引並重新創建;
  • 如果字段已存在非TTL單字段索引,則無法在同一字段上創建TTL索引,因為無法在相同key創建不同類型的的索引。 要將非TTL單字段索引更改為TTL索引,必須先刪除索引並使用expireAfterSeconds選項重新創建。

3.2 惟一性索引(Unique Indexes)

唯一索引可確保索引字段不存儲重複值; 即強制索引字段的唯一性。 默認情況下,MongoDB在創建集合期間在_id字段上創建唯一索引。創建方式如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

第二步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

數據過期類型:

  • 當指定時間到了過期的閾值數據就會過期並刪除;
  • 如果字段是數組,並且索引中有多個日期值,MongoDB使用數組中最低(即最早)的日期值來計算到期閾值;
  • 如果文檔(document)中的索引字段不是日期或包含日期值的數組,則文檔(document)將不會過期;
  • 如果文檔(document)不包含索引字段,則文檔(document)不會過期。

TTL索引特有限制:

  • TTL索引是單字段索引。 複合索引不支持TTL並忽略expireAfterSeconds選項;
  • _id屬性不支持TTL索引;
  • 無法在上限集合上創建TTL索引,因為MongoDB無法從上限集合中刪除文檔;
  • 不能使用createIndex()方法來更改現有索引的expireAfterSeconds值。而是將collMod數據庫命令與索引集合標誌結合使用。 否則,要更改現有索引的選項的值,必須先刪除索引並重新創建;
  • 如果字段已存在非TTL單字段索引,則無法在同一字段上創建TTL索引,因為無法在相同key創建不同類型的的索引。 要將非TTL單字段索引更改為TTL索引,必須先刪除索引並使用expireAfterSeconds選項重新創建。

3.2 惟一性索引(Unique Indexes)

唯一索引可確保索引字段不存儲重複值; 即強制索引字段的唯一性。 默認情況下,MongoDB在創建集合期間在_id字段上創建唯一索引。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

單個字段創建方式,示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

第二步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

數據過期類型:

  • 當指定時間到了過期的閾值數據就會過期並刪除;
  • 如果字段是數組,並且索引中有多個日期值,MongoDB使用數組中最低(即最早)的日期值來計算到期閾值;
  • 如果文檔(document)中的索引字段不是日期或包含日期值的數組,則文檔(document)將不會過期;
  • 如果文檔(document)不包含索引字段,則文檔(document)不會過期。

TTL索引特有限制:

  • TTL索引是單字段索引。 複合索引不支持TTL並忽略expireAfterSeconds選項;
  • _id屬性不支持TTL索引;
  • 無法在上限集合上創建TTL索引,因為MongoDB無法從上限集合中刪除文檔;
  • 不能使用createIndex()方法來更改現有索引的expireAfterSeconds值。而是將collMod數據庫命令與索引集合標誌結合使用。 否則,要更改現有索引的選項的值,必須先刪除索引並重新創建;
  • 如果字段已存在非TTL單字段索引,則無法在同一字段上創建TTL索引,因為無法在相同key創建不同類型的的索引。 要將非TTL單字段索引更改為TTL索引,必須先刪除索引並使用expireAfterSeconds選項重新創建。

3.2 惟一性索引(Unique Indexes)

唯一索引可確保索引字段不存儲重複值; 即強制索引字段的唯一性。 默認情況下,MongoDB在創建集合期間在_id字段上創建唯一索引。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

單個字段創建方式,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一性複合索引: 還可以對複合索引強制執行唯一約束。 如果對複合索引使用唯一約束,則MongoDB將對索引鍵值的組合強制實施唯一性。示例如下

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

第二步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

數據過期類型:

  • 當指定時間到了過期的閾值數據就會過期並刪除;
  • 如果字段是數組,並且索引中有多個日期值,MongoDB使用數組中最低(即最早)的日期值來計算到期閾值;
  • 如果文檔(document)中的索引字段不是日期或包含日期值的數組,則文檔(document)將不會過期;
  • 如果文檔(document)不包含索引字段,則文檔(document)不會過期。

TTL索引特有限制:

  • TTL索引是單字段索引。 複合索引不支持TTL並忽略expireAfterSeconds選項;
  • _id屬性不支持TTL索引;
  • 無法在上限集合上創建TTL索引,因為MongoDB無法從上限集合中刪除文檔;
  • 不能使用createIndex()方法來更改現有索引的expireAfterSeconds值。而是將collMod數據庫命令與索引集合標誌結合使用。 否則,要更改現有索引的選項的值,必須先刪除索引並重新創建;
  • 如果字段已存在非TTL單字段索引,則無法在同一字段上創建TTL索引,因為無法在相同key創建不同類型的的索引。 要將非TTL單字段索引更改為TTL索引,必須先刪除索引並使用expireAfterSeconds選項重新創建。

3.2 惟一性索引(Unique Indexes)

唯一索引可確保索引字段不存儲重複值; 即強制索引字段的唯一性。 默認情況下,MongoDB在創建集合期間在_id字段上創建唯一索引。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

單個字段創建方式,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一性複合索引: 還可以對複合索引強制執行唯一約束。 如果對複合索引使用唯一約束,則MongoDB將對索引鍵值的組合強制實施唯一性。示例如下

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一多鍵索引:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

第二步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

數據過期類型:

  • 當指定時間到了過期的閾值數據就會過期並刪除;
  • 如果字段是數組,並且索引中有多個日期值,MongoDB使用數組中最低(即最早)的日期值來計算到期閾值;
  • 如果文檔(document)中的索引字段不是日期或包含日期值的數組,則文檔(document)將不會過期;
  • 如果文檔(document)不包含索引字段,則文檔(document)不會過期。

TTL索引特有限制:

  • TTL索引是單字段索引。 複合索引不支持TTL並忽略expireAfterSeconds選項;
  • _id屬性不支持TTL索引;
  • 無法在上限集合上創建TTL索引,因為MongoDB無法從上限集合中刪除文檔;
  • 不能使用createIndex()方法來更改現有索引的expireAfterSeconds值。而是將collMod數據庫命令與索引集合標誌結合使用。 否則,要更改現有索引的選項的值,必須先刪除索引並重新創建;
  • 如果字段已存在非TTL單字段索引,則無法在同一字段上創建TTL索引,因為無法在相同key創建不同類型的的索引。 要將非TTL單字段索引更改為TTL索引,必須先刪除索引並使用expireAfterSeconds選項重新創建。

3.2 惟一性索引(Unique Indexes)

唯一索引可確保索引字段不存儲重複值; 即強制索引字段的唯一性。 默認情況下,MongoDB在創建集合期間在_id字段上創建唯一索引。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

單個字段創建方式,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一性複合索引: 還可以對複合索引強制執行唯一約束。 如果對複合索引使用唯一約束,則MongoDB將對索引鍵值的組合強制實施唯一性。示例如下

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一多鍵索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建唯一索引到副本或者分片中: 對於副本集和分片集群,使用滾動過程創建唯一索引需要在過程中停止對集合的所有寫入。 如果在過程中無法停止對集合的所有寫入,請不要使用滾動過程。 相反,通過以下方式在集合上構建唯一索引:

  • 在主服務器上為副本集發出db.collection.createIndex()
  • 在mongos上為分片群集發出db.collection.createIndex()

NOTE:詳細解析可以看

限制:

  • 如果集合已經包含超出索引的唯一約束的數據(即有重複數據),則MongoDB無法在指定的索引字段上創建唯一索引。
  • 不能在hash索引上創建唯一索引
  • 唯一約束適用於Collection中的一個Document。由於約束適用於單文檔document,因此對於唯一的多鍵索引,只要該文檔document的索引鍵值不與另一個文檔document的索引鍵值重複,文檔就可能具有導致重複索引鍵值的數組元素。 在這種情況下,重複索引記錄僅插入索引一次。
  • 分片Collection唯一索引只能如下:
  • 1).分片鍵上的索引
  • 2).分片鍵是前綴的複合索引
  • 3).默認的_id索引; 但是,如果_id字段不是分片鍵或分片鍵的前綴,則_id索引僅對每個分片強制執行唯一性約束。如果_id字段不是分片鍵,也不是分片鍵的前綴,MongoDB希望應用程序在分片中強制執行_id值的唯一性。

3.3 部分索引(Partial Indexes)

部分索引通過指定的過濾表達式去達到局部搜索。通過db.collection.createIndex()方法中增加partialFilterExpression屬性創建,過濾表達式如下:

  • 等式表達式(即 file:value或使用$eq運算符)
  • $exists表達式
  • $gt,$gte,$lt,$lte 表達式
  • $type表達式
  • $and

示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

第二步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

數據過期類型:

  • 當指定時間到了過期的閾值數據就會過期並刪除;
  • 如果字段是數組,並且索引中有多個日期值,MongoDB使用數組中最低(即最早)的日期值來計算到期閾值;
  • 如果文檔(document)中的索引字段不是日期或包含日期值的數組,則文檔(document)將不會過期;
  • 如果文檔(document)不包含索引字段,則文檔(document)不會過期。

TTL索引特有限制:

  • TTL索引是單字段索引。 複合索引不支持TTL並忽略expireAfterSeconds選項;
  • _id屬性不支持TTL索引;
  • 無法在上限集合上創建TTL索引,因為MongoDB無法從上限集合中刪除文檔;
  • 不能使用createIndex()方法來更改現有索引的expireAfterSeconds值。而是將collMod數據庫命令與索引集合標誌結合使用。 否則,要更改現有索引的選項的值,必須先刪除索引並重新創建;
  • 如果字段已存在非TTL單字段索引,則無法在同一字段上創建TTL索引,因為無法在相同key創建不同類型的的索引。 要將非TTL單字段索引更改為TTL索引,必須先刪除索引並使用expireAfterSeconds選項重新創建。

3.2 惟一性索引(Unique Indexes)

唯一索引可確保索引字段不存儲重複值; 即強制索引字段的唯一性。 默認情況下,MongoDB在創建集合期間在_id字段上創建唯一索引。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

單個字段創建方式,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一性複合索引: 還可以對複合索引強制執行唯一約束。 如果對複合索引使用唯一約束,則MongoDB將對索引鍵值的組合強制實施唯一性。示例如下

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一多鍵索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建唯一索引到副本或者分片中: 對於副本集和分片集群,使用滾動過程創建唯一索引需要在過程中停止對集合的所有寫入。 如果在過程中無法停止對集合的所有寫入,請不要使用滾動過程。 相反,通過以下方式在集合上構建唯一索引:

  • 在主服務器上為副本集發出db.collection.createIndex()
  • 在mongos上為分片群集發出db.collection.createIndex()

NOTE:詳細解析可以看

限制:

  • 如果集合已經包含超出索引的唯一約束的數據(即有重複數據),則MongoDB無法在指定的索引字段上創建唯一索引。
  • 不能在hash索引上創建唯一索引
  • 唯一約束適用於Collection中的一個Document。由於約束適用於單文檔document,因此對於唯一的多鍵索引,只要該文檔document的索引鍵值不與另一個文檔document的索引鍵值重複,文檔就可能具有導致重複索引鍵值的數組元素。 在這種情況下,重複索引記錄僅插入索引一次。
  • 分片Collection唯一索引只能如下:
  • 1).分片鍵上的索引
  • 2).分片鍵是前綴的複合索引
  • 3).默認的_id索引; 但是,如果_id字段不是分片鍵或分片鍵的前綴,則_id索引僅對每個分片強制執行唯一性約束。如果_id字段不是分片鍵,也不是分片鍵的前綴,MongoDB希望應用程序在分片中強制執行_id值的唯一性。

3.3 部分索引(Partial Indexes)

部分索引通過指定的過濾表達式去達到局部搜索。通過db.collection.createIndex()方法中增加partialFilterExpression屬性創建,過濾表達式如下:

  • 等式表達式(即 file:value或使用$eq運算符)
  • $exists表達式
  • $gt,$gte,$lt,$lte 表達式
  • $type表達式
  • $and

示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

其中:

  • (1)查詢: 查詢條件{ $gte: 8 }於創建索引條件{ $gt: 5 }可以構成一個完整集(查詢條件是創建索引條件的子集,即大於5可以包含大於等於 8),可以使用部分索引查詢。
  • (2)查詢: 條件達不到完整集,MongoDB將不會將部分索引用於查詢或排序操作。
  • (3)查詢: 次查詢沒有使用過濾表達式,也不會使用部分索引,因為要使用部分索引,查詢必須包含過濾器表達式(或指定過濾器表達式子集的已修改過濾器表達式)作為其查詢條件的一部分

限制:

  • 不可以僅通過過濾表達式創建多個局部索引;
  • 不可以同時使用局部索引和稀疏索引(sparse index);
  • _id索引不能使用局部索引,分片索引(shard key index)也不能使用局部索引;
  • 同時指定partialFilterExpression和唯一約束,則唯一約束僅適用於滿足過濾器表達式的文檔。 如果Document不符合篩選條件,則具有唯一約束的部分索引是允許插入不符合唯一約束的Document。

3.4 稀疏索引(Sparse Indexes)

稀疏索只引搜索包含有索引字段的文檔的條目,跳過索引鍵不存在的文檔,即稀疏索引不會搜索不包含稀疏索引的文檔。默認情況下, 2dsphere (version 2), 2d, geoHaystack, 全文索引等總是稀疏索引。創建方式db.collection.createIndex()方法增加sparse屬性,如下所示:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

第二步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

數據過期類型:

  • 當指定時間到了過期的閾值數據就會過期並刪除;
  • 如果字段是數組,並且索引中有多個日期值,MongoDB使用數組中最低(即最早)的日期值來計算到期閾值;
  • 如果文檔(document)中的索引字段不是日期或包含日期值的數組,則文檔(document)將不會過期;
  • 如果文檔(document)不包含索引字段,則文檔(document)不會過期。

TTL索引特有限制:

  • TTL索引是單字段索引。 複合索引不支持TTL並忽略expireAfterSeconds選項;
  • _id屬性不支持TTL索引;
  • 無法在上限集合上創建TTL索引,因為MongoDB無法從上限集合中刪除文檔;
  • 不能使用createIndex()方法來更改現有索引的expireAfterSeconds值。而是將collMod數據庫命令與索引集合標誌結合使用。 否則,要更改現有索引的選項的值,必須先刪除索引並重新創建;
  • 如果字段已存在非TTL單字段索引,則無法在同一字段上創建TTL索引,因為無法在相同key創建不同類型的的索引。 要將非TTL單字段索引更改為TTL索引,必須先刪除索引並使用expireAfterSeconds選項重新創建。

3.2 惟一性索引(Unique Indexes)

唯一索引可確保索引字段不存儲重複值; 即強制索引字段的唯一性。 默認情況下,MongoDB在創建集合期間在_id字段上創建唯一索引。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

單個字段創建方式,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一性複合索引: 還可以對複合索引強制執行唯一約束。 如果對複合索引使用唯一約束,則MongoDB將對索引鍵值的組合強制實施唯一性。示例如下

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一多鍵索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建唯一索引到副本或者分片中: 對於副本集和分片集群,使用滾動過程創建唯一索引需要在過程中停止對集合的所有寫入。 如果在過程中無法停止對集合的所有寫入,請不要使用滾動過程。 相反,通過以下方式在集合上構建唯一索引:

  • 在主服務器上為副本集發出db.collection.createIndex()
  • 在mongos上為分片群集發出db.collection.createIndex()

NOTE:詳細解析可以看

限制:

  • 如果集合已經包含超出索引的唯一約束的數據(即有重複數據),則MongoDB無法在指定的索引字段上創建唯一索引。
  • 不能在hash索引上創建唯一索引
  • 唯一約束適用於Collection中的一個Document。由於約束適用於單文檔document,因此對於唯一的多鍵索引,只要該文檔document的索引鍵值不與另一個文檔document的索引鍵值重複,文檔就可能具有導致重複索引鍵值的數組元素。 在這種情況下,重複索引記錄僅插入索引一次。
  • 分片Collection唯一索引只能如下:
  • 1).分片鍵上的索引
  • 2).分片鍵是前綴的複合索引
  • 3).默認的_id索引; 但是,如果_id字段不是分片鍵或分片鍵的前綴,則_id索引僅對每個分片強制執行唯一性約束。如果_id字段不是分片鍵,也不是分片鍵的前綴,MongoDB希望應用程序在分片中強制執行_id值的唯一性。

3.3 部分索引(Partial Indexes)

部分索引通過指定的過濾表達式去達到局部搜索。通過db.collection.createIndex()方法中增加partialFilterExpression屬性創建,過濾表達式如下:

  • 等式表達式(即 file:value或使用$eq運算符)
  • $exists表達式
  • $gt,$gte,$lt,$lte 表達式
  • $type表達式
  • $and

示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

其中:

  • (1)查詢: 查詢條件{ $gte: 8 }於創建索引條件{ $gt: 5 }可以構成一個完整集(查詢條件是創建索引條件的子集,即大於5可以包含大於等於 8),可以使用部分索引查詢。
  • (2)查詢: 條件達不到完整集,MongoDB將不會將部分索引用於查詢或排序操作。
  • (3)查詢: 次查詢沒有使用過濾表達式,也不會使用部分索引,因為要使用部分索引,查詢必須包含過濾器表達式(或指定過濾器表達式子集的已修改過濾器表達式)作為其查詢條件的一部分

限制:

  • 不可以僅通過過濾表達式創建多個局部索引;
  • 不可以同時使用局部索引和稀疏索引(sparse index);
  • _id索引不能使用局部索引,分片索引(shard key index)也不能使用局部索引;
  • 同時指定partialFilterExpression和唯一約束,則唯一約束僅適用於滿足過濾器表達式的文檔。 如果Document不符合篩選條件,則具有唯一約束的部分索引是允許插入不符合唯一約束的Document。

3.4 稀疏索引(Sparse Indexes)

稀疏索只引搜索包含有索引字段的文檔的條目,跳過索引鍵不存在的文檔,即稀疏索引不會搜索不包含稀疏索引的文檔。默認情況下, 2dsphere (version 2), 2d, geoHaystack, 全文索引等總是稀疏索引。創建方式db.collection.createIndex()方法增加sparse屬性,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

稀疏索引不被使用的情況: 如果稀疏索引會導致查詢和排序操作的結果集不完整,MongoDB將不會使用該索引,除非hint()示顯式指定索引。

稀疏複合索引:

  • 對於包含上升/下降排序的稀疏複合索引,只要複合索引中的一個key 索引存在都會被檢測出來
  • 對於包含上升/下降排序的包含地理空間可以的稀疏複合索引,只有存在地理空間key才能被檢測出來
  • 對於包含上升/下降排序的全文索引的稀疏複合索引,只有存在全文索引索引才可以被檢測

稀疏索引與唯一性: 一個既包含稀疏又包含唯一的索引避免集合上存在一些重複值得文檔,但是允許多個文檔忽略該鍵。滿足稀疏索引和唯一性操作其兩個限制都要遵循。

整合示例如下:

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

第二步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

數據過期類型:

  • 當指定時間到了過期的閾值數據就會過期並刪除;
  • 如果字段是數組,並且索引中有多個日期值,MongoDB使用數組中最低(即最早)的日期值來計算到期閾值;
  • 如果文檔(document)中的索引字段不是日期或包含日期值的數組,則文檔(document)將不會過期;
  • 如果文檔(document)不包含索引字段,則文檔(document)不會過期。

TTL索引特有限制:

  • TTL索引是單字段索引。 複合索引不支持TTL並忽略expireAfterSeconds選項;
  • _id屬性不支持TTL索引;
  • 無法在上限集合上創建TTL索引,因為MongoDB無法從上限集合中刪除文檔;
  • 不能使用createIndex()方法來更改現有索引的expireAfterSeconds值。而是將collMod數據庫命令與索引集合標誌結合使用。 否則,要更改現有索引的選項的值,必須先刪除索引並重新創建;
  • 如果字段已存在非TTL單字段索引,則無法在同一字段上創建TTL索引,因為無法在相同key創建不同類型的的索引。 要將非TTL單字段索引更改為TTL索引,必須先刪除索引並使用expireAfterSeconds選項重新創建。

3.2 惟一性索引(Unique Indexes)

唯一索引可確保索引字段不存儲重複值; 即強制索引字段的唯一性。 默認情況下,MongoDB在創建集合期間在_id字段上創建唯一索引。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

單個字段創建方式,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一性複合索引: 還可以對複合索引強制執行唯一約束。 如果對複合索引使用唯一約束,則MongoDB將對索引鍵值的組合強制實施唯一性。示例如下

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一多鍵索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建唯一索引到副本或者分片中: 對於副本集和分片集群,使用滾動過程創建唯一索引需要在過程中停止對集合的所有寫入。 如果在過程中無法停止對集合的所有寫入,請不要使用滾動過程。 相反,通過以下方式在集合上構建唯一索引:

  • 在主服務器上為副本集發出db.collection.createIndex()
  • 在mongos上為分片群集發出db.collection.createIndex()

NOTE:詳細解析可以看

限制:

  • 如果集合已經包含超出索引的唯一約束的數據(即有重複數據),則MongoDB無法在指定的索引字段上創建唯一索引。
  • 不能在hash索引上創建唯一索引
  • 唯一約束適用於Collection中的一個Document。由於約束適用於單文檔document,因此對於唯一的多鍵索引,只要該文檔document的索引鍵值不與另一個文檔document的索引鍵值重複,文檔就可能具有導致重複索引鍵值的數組元素。 在這種情況下,重複索引記錄僅插入索引一次。
  • 分片Collection唯一索引只能如下:
  • 1).分片鍵上的索引
  • 2).分片鍵是前綴的複合索引
  • 3).默認的_id索引; 但是,如果_id字段不是分片鍵或分片鍵的前綴,則_id索引僅對每個分片強制執行唯一性約束。如果_id字段不是分片鍵,也不是分片鍵的前綴,MongoDB希望應用程序在分片中強制執行_id值的唯一性。

3.3 部分索引(Partial Indexes)

部分索引通過指定的過濾表達式去達到局部搜索。通過db.collection.createIndex()方法中增加partialFilterExpression屬性創建,過濾表達式如下:

  • 等式表達式(即 file:value或使用$eq運算符)
  • $exists表達式
  • $gt,$gte,$lt,$lte 表達式
  • $type表達式
  • $and

示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

其中:

  • (1)查詢: 查詢條件{ $gte: 8 }於創建索引條件{ $gt: 5 }可以構成一個完整集(查詢條件是創建索引條件的子集,即大於5可以包含大於等於 8),可以使用部分索引查詢。
  • (2)查詢: 條件達不到完整集,MongoDB將不會將部分索引用於查詢或排序操作。
  • (3)查詢: 次查詢沒有使用過濾表達式,也不會使用部分索引,因為要使用部分索引,查詢必須包含過濾器表達式(或指定過濾器表達式子集的已修改過濾器表達式)作為其查詢條件的一部分

限制:

  • 不可以僅通過過濾表達式創建多個局部索引;
  • 不可以同時使用局部索引和稀疏索引(sparse index);
  • _id索引不能使用局部索引,分片索引(shard key index)也不能使用局部索引;
  • 同時指定partialFilterExpression和唯一約束,則唯一約束僅適用於滿足過濾器表達式的文檔。 如果Document不符合篩選條件,則具有唯一約束的部分索引是允許插入不符合唯一約束的Document。

3.4 稀疏索引(Sparse Indexes)

稀疏索只引搜索包含有索引字段的文檔的條目,跳過索引鍵不存在的文檔,即稀疏索引不會搜索不包含稀疏索引的文檔。默認情況下, 2dsphere (version 2), 2d, geoHaystack, 全文索引等總是稀疏索引。創建方式db.collection.createIndex()方法增加sparse屬性,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

稀疏索引不被使用的情況: 如果稀疏索引會導致查詢和排序操作的結果集不完整,MongoDB將不會使用該索引,除非hint()示顯式指定索引。

稀疏複合索引:

  • 對於包含上升/下降排序的稀疏複合索引,只要複合索引中的一個key 索引存在都會被檢測出來
  • 對於包含上升/下降排序的包含地理空間可以的稀疏複合索引,只有存在地理空間key才能被檢測出來
  • 對於包含上升/下降排序的全文索引的稀疏複合索引,只有存在全文索引索引才可以被檢測

稀疏索引與唯一性: 一個既包含稀疏又包含唯一的索引避免集合上存在一些重複值得文檔,但是允許多個文檔忽略該鍵。滿足稀疏索引和唯一性操作其兩個限制都要遵循。

整合示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

其中:

  • (1)查詢: 可以使用稀疏索引查詢,返回完整集:{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
  • (2)查詢: 即使排序是通過索引字段進行的,MongoDB也不會選擇稀疏索引來完成查詢以返回完整的結果:
  • { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
  • { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
  • { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
  • (3)查詢: 使用hint()返回所需完整集:
  • { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
  • { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

4. 其他事項

4.1 索引策略

索引策略:

  • 應用程序的最佳索引必須考慮許多因素,包括期望查詢的類型,讀取與寫入的比率以及系統上的可用內存量。
  • 在開發索引策略時,您應該深入瞭解應用程序的查詢。在構建索引之前,映射將要運行的查詢類型,以便您可以構建引用這些字段的索引。索引具有性能成本,但是對於大型數據集上的頻繁查詢而言,它們的價值更高。考慮應用程序中每個查詢的相對頻率以及查詢是否證明索引是合理的。
  • 設計索引的最佳總體策略是使用與您將在生產中運行的數據集類似的數據集來分析各種索引配置,以查看哪些配置性能最佳。檢查為集合創建的當前索引,以確保它們支持您當前和計劃的查詢。如果不再使用索引,請刪除索引。
  • 通常,MongoDB僅使用一個索引來完成大多數查詢。但是,$或查詢的每個子句可能使用不同的索引,從2.6開始,MongoDB可以使用多個索引的交集

粉絲福利

"
淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

前言

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結構。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當的索引,MongoDB可以使用索引來限制它必須查詢的文檔document的數量,特別是在處理大量數據時,所以選擇正確的索引是很關鍵的、重要的。

創建索引,需要考慮的問題:

  • 每個索引至少需要數據空間為8kb;
  • 添加索引會對寫入操作會產生一些性能影響。 對於具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對於具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處於索引處於action狀態時,每個索引都會佔用磁盤空間和內存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 複合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創建

索引創建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數,可選參數列表如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.5 查看索引創建過程以及終止索引創建

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標準

MongoDB提供了許多索引使用和操作的度量標準,在分析數據庫的索引使用時可能需要考慮這些度量標準,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

1.8 後臺索引操作

在密集(快達到數據庫最大容量)Collection創建索引:在默認情況下,在密集的Collection(快達到數據庫最大容量)時創建索引,會阻止其他操作。在給密集的Collection(快達到數據庫最大容量)創建索引時, 索引構建完成之前,保存Collection的數據庫不可用於讀取或寫入操作。 任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作都將等待不是後臺進程的索引構建完成。

因此可以使用background屬性進行設置後臺索引創建,操作如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創建索引,默認情況下,所有的集合(collections)會在_id字段中創建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標準的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序對項目進行排序的索引,“-1”指定按降序對項目進行排序的索引。如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在單個字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創建索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.2 複合索引(Compound Index)

複合索引指的是將多個key組合到一起創建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何複合索引都限制了32個字段;
  • 無法創建具有散列索引(hash index)類型的複合索引。如果嘗試創建包含散列索引字段的複合索引,則會報錯;
  • 複合索引創建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對於單字段索引,鍵的排序順序無關緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對於複合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,複合索引還可以支持與索引字段的前綴匹配的查詢。

創建複合索引的格式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

排序順序,兩個字段的複合索引示例,index{userid:1,score:-1},先userid的value排序,然後再userid排序基礎下進行score排序。如下圖:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建複合索引,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

複合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數組的每個元素都創建索引,多鍵索引可以建立在字符串、數字等key或者內嵌文檔(document)的數組上,如果索引字段包含數組值,MongoDB會自動確定是否創建多鍵索引; 您不需要手動指定多鍵類型。 其中創建方式:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現索引邊界(索引邊界即是查詢過程中索引能查找的範圍)的計算,並計算必須遵循一些規則。即當多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者並集等來判斷這些條件索引字段的邊界最終產生一個最小的查找範圍。可以分情況:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對於給定的數組字段,假定一個查詢使用了數組的多個條件字段並且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

查詢條件分別為大於等於3、小於等於6,其中 (1)中使用了$elemMatch連接查詢條件,會產生一個交集ratings:[[3,6]。在(2)查詢中,沒使用$elemMatch,則不會產生交集,只要滿足任何一個條件即可。

2).並集邊界

並集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相併這兩個邊界的結果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法並集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數組字段的組合索引

一個組合索引的索引字段是數組,例如一個survey collection集合document文檔中含有item字段和ratings數組字段,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

4).內嵌文檔document的數組上建立組合索引

如果數組中包含內嵌文檔document,想在包含的內嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數組類型的字段和數組類型字段的並集

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決於查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行並集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。

6).數組字段索引的並集邊界

在數組內部並集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對於內嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數組上並集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創建組合索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

MongoDB可以使用並集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

7). 還有不使用$elemMatch進行查詢以及不完整的路徑上使用$elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對於一個組合多鍵索引,每個索引文檔最多隻能有一個索引字段的值是數組。如果組合多鍵索引已經存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當一個查詢聲明把數組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數組的第一個元素,但是不能使用多鍵索引掃描來找出整個數組。代替方案是當使用多鍵索引查詢出數組的第一個元素之後,MongoDB再對過濾之後的文檔再進行一次數組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內容,對字符串與字符串數組創建全文可搜索的索引 。 這些全文索引不存儲特定於語言的停用詞(例如“the”,“a”,“或”),並且阻止document集合中的單詞僅存儲根詞。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且MongoDB提供權重以及通配符的創建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創建時指定, 或者使用language_override屬性 覆蓋掉創建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

權重

每個全文索引可以通過設置權重來分配不同的搜索程度,默認權重為1,對於文檔中的每個索引字段,MongoDB將匹配數乘以權重並將結果相加。 使用此總和,MongoDB然後計算文檔的分數,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

content權重為10,keywords為5,about為默認權重1,因此可以得出content對於keywords查詢頻率高於2倍,而對於about字段則是10倍。

通配符全文索引

在多個字段上創建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串數據。例如:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創建索引期間為特定字段指定權重,以控制結果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多隻有一個全文索引,
  • Text Search 和Hints函數,如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是複合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 複合索引:複合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些複合索引具有以下限制:
  • 1).複合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果複合文本索引包括文本索引鍵之前的鍵,則執行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創建複合文本索引時,必須在索引規範文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數來計算索引字段值的散列值。 散列函數會摺疊嵌入的文檔並計算整個值的散列值,但不支持多鍵(即數組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基於散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數據。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,並且字段類型必須是date類型或者包含有date類型的數組,MongoDB可以使用它在一定時間後或在特定時鐘時間自動從集合中刪除文檔。 數據到期對於某些類型的信息非常有用,例如機器生成的事件數據,日誌和會話信息,這些信息只需要在數據庫中持續有限的時間。

創建TTL索引方法,和普通索引的創建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數組的字段上創建TTL索引,並指定expireAfterSeconds值為0.對於集合中的每個文檔,設置 索引日期字段為與文檔到期時間對應的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

第二步:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

數據過期類型:

  • 當指定時間到了過期的閾值數據就會過期並刪除;
  • 如果字段是數組,並且索引中有多個日期值,MongoDB使用數組中最低(即最早)的日期值來計算到期閾值;
  • 如果文檔(document)中的索引字段不是日期或包含日期值的數組,則文檔(document)將不會過期;
  • 如果文檔(document)不包含索引字段,則文檔(document)不會過期。

TTL索引特有限制:

  • TTL索引是單字段索引。 複合索引不支持TTL並忽略expireAfterSeconds選項;
  • _id屬性不支持TTL索引;
  • 無法在上限集合上創建TTL索引,因為MongoDB無法從上限集合中刪除文檔;
  • 不能使用createIndex()方法來更改現有索引的expireAfterSeconds值。而是將collMod數據庫命令與索引集合標誌結合使用。 否則,要更改現有索引的選項的值,必須先刪除索引並重新創建;
  • 如果字段已存在非TTL單字段索引,則無法在同一字段上創建TTL索引,因為無法在相同key創建不同類型的的索引。 要將非TTL單字段索引更改為TTL索引,必須先刪除索引並使用expireAfterSeconds選項重新創建。

3.2 惟一性索引(Unique Indexes)

唯一索引可確保索引字段不存儲重複值; 即強制索引字段的唯一性。 默認情況下,MongoDB在創建集合期間在_id字段上創建唯一索引。創建方式如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

單個字段創建方式,示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一性複合索引: 還可以對複合索引強制執行唯一約束。 如果對複合索引使用唯一約束,則MongoDB將對索引鍵值的組合強制實施唯一性。示例如下

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

唯一多鍵索引:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

創建唯一索引到副本或者分片中: 對於副本集和分片集群,使用滾動過程創建唯一索引需要在過程中停止對集合的所有寫入。 如果在過程中無法停止對集合的所有寫入,請不要使用滾動過程。 相反,通過以下方式在集合上構建唯一索引:

  • 在主服務器上為副本集發出db.collection.createIndex()
  • 在mongos上為分片群集發出db.collection.createIndex()

NOTE:詳細解析可以看

限制:

  • 如果集合已經包含超出索引的唯一約束的數據(即有重複數據),則MongoDB無法在指定的索引字段上創建唯一索引。
  • 不能在hash索引上創建唯一索引
  • 唯一約束適用於Collection中的一個Document。由於約束適用於單文檔document,因此對於唯一的多鍵索引,只要該文檔document的索引鍵值不與另一個文檔document的索引鍵值重複,文檔就可能具有導致重複索引鍵值的數組元素。 在這種情況下,重複索引記錄僅插入索引一次。
  • 分片Collection唯一索引只能如下:
  • 1).分片鍵上的索引
  • 2).分片鍵是前綴的複合索引
  • 3).默認的_id索引; 但是,如果_id字段不是分片鍵或分片鍵的前綴,則_id索引僅對每個分片強制執行唯一性約束。如果_id字段不是分片鍵,也不是分片鍵的前綴,MongoDB希望應用程序在分片中強制執行_id值的唯一性。

3.3 部分索引(Partial Indexes)

部分索引通過指定的過濾表達式去達到局部搜索。通過db.collection.createIndex()方法中增加partialFilterExpression屬性創建,過濾表達式如下:

  • 等式表達式(即 file:value或使用$eq運算符)
  • $exists表達式
  • $gt,$gte,$lt,$lte 表達式
  • $type表達式
  • $and

示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

其中:

  • (1)查詢: 查詢條件{ $gte: 8 }於創建索引條件{ $gt: 5 }可以構成一個完整集(查詢條件是創建索引條件的子集,即大於5可以包含大於等於 8),可以使用部分索引查詢。
  • (2)查詢: 條件達不到完整集,MongoDB將不會將部分索引用於查詢或排序操作。
  • (3)查詢: 次查詢沒有使用過濾表達式,也不會使用部分索引,因為要使用部分索引,查詢必須包含過濾器表達式(或指定過濾器表達式子集的已修改過濾器表達式)作為其查詢條件的一部分

限制:

  • 不可以僅通過過濾表達式創建多個局部索引;
  • 不可以同時使用局部索引和稀疏索引(sparse index);
  • _id索引不能使用局部索引,分片索引(shard key index)也不能使用局部索引;
  • 同時指定partialFilterExpression和唯一約束,則唯一約束僅適用於滿足過濾器表達式的文檔。 如果Document不符合篩選條件,則具有唯一約束的部分索引是允許插入不符合唯一約束的Document。

3.4 稀疏索引(Sparse Indexes)

稀疏索只引搜索包含有索引字段的文檔的條目,跳過索引鍵不存在的文檔,即稀疏索引不會搜索不包含稀疏索引的文檔。默認情況下, 2dsphere (version 2), 2d, geoHaystack, 全文索引等總是稀疏索引。創建方式db.collection.createIndex()方法增加sparse屬性,如下所示:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

稀疏索引不被使用的情況: 如果稀疏索引會導致查詢和排序操作的結果集不完整,MongoDB將不會使用該索引,除非hint()示顯式指定索引。

稀疏複合索引:

  • 對於包含上升/下降排序的稀疏複合索引,只要複合索引中的一個key 索引存在都會被檢測出來
  • 對於包含上升/下降排序的包含地理空間可以的稀疏複合索引,只有存在地理空間key才能被檢測出來
  • 對於包含上升/下降排序的全文索引的稀疏複合索引,只有存在全文索引索引才可以被檢測

稀疏索引與唯一性: 一個既包含稀疏又包含唯一的索引避免集合上存在一些重複值得文檔,但是允許多個文檔忽略該鍵。滿足稀疏索引和唯一性操作其兩個限制都要遵循。

整合示例如下:

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

其中:

  • (1)查詢: 可以使用稀疏索引查詢,返回完整集:{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
  • (2)查詢: 即使排序是通過索引字段進行的,MongoDB也不會選擇稀疏索引來完成查詢以返回完整的結果:
  • { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
  • { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
  • { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
  • (3)查詢: 使用hint()返回所需完整集:
  • { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
  • { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

4. 其他事項

4.1 索引策略

索引策略:

  • 應用程序的最佳索引必須考慮許多因素,包括期望查詢的類型,讀取與寫入的比率以及系統上的可用內存量。
  • 在開發索引策略時,您應該深入瞭解應用程序的查詢。在構建索引之前,映射將要運行的查詢類型,以便您可以構建引用這些字段的索引。索引具有性能成本,但是對於大型數據集上的頻繁查詢而言,它們的價值更高。考慮應用程序中每個查詢的相對頻率以及查詢是否證明索引是合理的。
  • 設計索引的最佳總體策略是使用與您將在生產中運行的數據集類似的數據集來分析各種索引配置,以查看哪些配置性能最佳。檢查為集合創建的當前索引,以確保它們支持您當前和計劃的查詢。如果不再使用索引,請刪除索引。
  • 通常,MongoDB僅使用一個索引來完成大多數查詢。但是,$或查詢的每個子句可能使用不同的索引,從2.6開始,MongoDB可以使用多個索引的交集

粉絲福利

淺入淺出MongonDB,教你輕鬆應對面試中遇到的MongonDB索引問題

如何獲取:

私信我回復 【資料】 即可獲取,

私信我回復 【資料】 即可獲取,

私信我回復 【資料】 即可獲取

"

相關推薦

推薦中...