DocumentDB - 索引記錄



預設情況下,DocumentDB 會在文件新增到資料庫後立即自動為文件中的每個屬性建立索引。但是,您可以進行控制並微調自己的索引策略,在某些特定文件和/或屬性不需要建立索引時,減少儲存和處理開銷。

告訴 DocumentDB 自動為每個屬性建立索引的預設索引策略適用於許多常見場景。但是,您也可以實現自定義策略,對要索引的內容和不索引的內容進行精確控制,以及其他與索引相關的功能。

DocumentDB 支援以下型別的索引:

  • 雜湊
  • 範圍

雜湊

雜湊索引能夠有效地查詢相等性,即在搜尋給定屬性等於精確值的文件時,而不是匹配一系列值(如小於、大於或介於)。

您可以使用雜湊索引執行範圍查詢,但 DocumentDB 將無法使用雜湊索引查詢匹配的文件,而需要依次掃描每個文件以確定是否應透過範圍查詢選擇它。

您將無法使用 ORDER BY 子句對僅具有雜湊索引的屬性排序文件。

範圍

為屬性定義的範圍索引,DocumentDB 允許對一系列值有效地查詢文件。它還允許您使用 ORDER BY 對該屬性上的查詢結果進行排序。

DocumentDB 允許您在任何或所有屬性上同時定義雜湊索引和範圍索引,這使得能夠有效地進行相等性和範圍查詢,以及 ORDER BY。

索引策略

每個集合都有一個索引策略,該策略規定在每個文件的每個屬性的數字和字串中使用哪種型別的索引。

  • 您還可以控制文件在新增到集合時是否自動建立索引。

  • 自動索引預設啟用,但在新增文件時可以覆蓋此行為,告訴 DocumentDB 不要索引該特定文件。

  • 您可以停用自動索引,以便預設情況下,文件在新增到集合時不會被索引。類似地,您可以在文件級別覆蓋此設定,並在將文件新增到集合時指示 DocumentDB 對其進行索引。這稱為手動索引。

包含/排除索引

索引策略還可以定義應包含在索引中或排除在索引之外的路徑或路徑。如果您知道文件的某些部分從未被查詢過,而某些部分卻被查詢過,則此功能很有用。

在這些情況下,您可以透過告訴 DocumentDB 只索引新增到集合的每個文件的這些特定部分來減少索引開銷。

自動索引

讓我們來看一個自動索引的簡單示例。

步驟 1 - 首先,我們建立一個名為 autoindexing 的集合,並且沒有顯式提供策略,此集合使用預設索引策略,這意味著在此集合上啟用了自動索引。

這裡我們使用基於 ID 的路由進行資料庫自連結,因此我們不需要知道它的資源 ID 或在建立集合之前查詢它。我們只需使用資料庫 ID,即 mydb。

步驟 2 - 現在讓我們建立兩個文件,兩個文件的姓氏都是 Upston。

private async static Task AutomaticIndexing(DocumentClient client) {
   Console.WriteLine();
   Console.WriteLine("**** Override Automatic Indexing ****");

   // Create collection with automatic indexing

   var collectionDefinition = new DocumentCollection {
      Id = "autoindexing"
   };
	
   var collection = await client.CreateDocumentCollectionAsync("dbs/mydb",
      collectionDefinition);

   // Add a document (indexed)
   dynamic indexedDocumentDefinition = new {
      id = "MARK",
      firstName = "Mark",
      lastName = "Upston",
      addressLine = "123 Main Street",
      city = "Brooklyn",
      state = "New York",
      zip = "11229",
   };
	
   Document indexedDocument = await client
      .CreateDocumentAsync("dbs/mydb/colls/autoindexing", indexedDocumentDefinition);
		
   // Add another document (request no indexing)
   dynamic unindexedDocumentDefinition = new {
      id = "JANE",
      firstName = "Jane",
      lastName = "Upston",
      addressLine = "123 Main Street",
      city = "Brooklyn",
      state = "New York",
      zip = "11229",
   };
	
   Document unindexedDocument = await client
      .CreateDocumentAsync("dbs/mydb/colls/autoindexing", unindexedDocumentDefinition,
      new RequestOptions { IndexingDirective = IndexingDirective.Exclude });

   //Unindexed document won't get returned when querying on non-ID (or selflink) property

   var doeDocs = client.CreateDocumentQuery("dbs/mydb/colls/autoindexing", "SELECT *
      FROM c WHERE c.lastName = 'Doe'").ToList();
		
   Console.WriteLine("Documents WHERE lastName = 'Doe': {0}", doeDocs.Count);

   // Unindexed document will get returned when using no WHERE clause

   var allDocs = client.CreateDocumentQuery("dbs/mydb/colls/autoindexing",
      "SELECT * FROM c").ToList();
   Console.WriteLine("All documents: {0}", allDocs.Count);
	
   // Unindexed document will get returned when querying by ID (or self-link) property
	
   Document janeDoc = client.CreateDocumentQuery("dbs/mydb/colls/autoindexing",
      "SELECT * FROM c WHERE c.id = 'JANE'").AsEnumerable().FirstOrDefault();
   Console.WriteLine("Unindexed document self-link: {0}", janeDoc.SelfLink);
	
   // Delete the collection
	
   await client.DeleteDocumentCollectionAsync("dbs/mydb/colls/autoindexing");
}

第一個是 Mark Upston,它被新增到集合中,然後根據預設索引策略立即自動建立索引。

但是,當為 Mark Upston 新增第二個文件時,我們已將請求選項與 IndexingDirective.Exclude 一起傳遞,該選項明確指示 DocumentDB 不要索引此文件,儘管集合的索引策略是如此。

最後,我們對這兩個文件有不同型別的查詢。

步驟 3 - 讓我們從 CreateDocumentClient 呼叫 AutomaticIndexing 任務。

private static async Task CreateDocumentClient() {
   // Create a new instance of the DocumentClient 
   using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) { 
      await AutomaticIndexing(client); 
   } 
}

編譯並執行上述程式碼後,您將收到以下輸出。

**** Override Automatic Indexing **** 
Documents WHERE lastName = 'Upston': 1 
All documents: 2 
Unindexed document self-link: dbs/kV5oAA==/colls/kV5oAOEkfQA=/docs/kV5oAOEkfQACA 
AAAAAAAAA==/

如您所見,我們有兩個這樣的文件,但查詢僅返回 Mark 的文件,因為 Mark 的文件未建立索引。如果我們再次查詢,不帶 WHERE 子句來檢索集合中的所有文件,那麼我們將獲得一個包含兩個文件的結果集,這是因為未建立索引的文件始終由沒有 WHERE 子句的查詢返回。

我們還可以透過其 ID 或自連結檢索未建立索引的文件。因此,當我們透過其 ID MARK 查詢 Mark 的文件時,我們看到 DocumentDB 返回了該文件,即使它未在集合中建立索引。

手動索引

讓我們來看一個透過覆蓋自動索引來進行手動索引的簡單示例。

步驟 1 - 首先,我們將建立一個名為 manualindexing 的集合,並透過顯式停用自動索引來覆蓋預設策略。這意味著,除非我們另行請求,否則新增到此集合的新文件將不會被索引。

private async static Task ManualIndexing(DocumentClient client) {
   Console.WriteLine();
   Console.WriteLine("**** Manual Indexing ****");
   // Create collection with manual indexing

   var collectionDefinition = new DocumentCollection {
      Id = "manualindexing",
      IndexingPolicy = new IndexingPolicy {
         Automatic = false,
      },
   };
	
   var collection = await client.CreateDocumentCollectionAsync("dbs/mydb",
      collectionDefinition);
		
   // Add a document (unindexed)
   dynamic unindexedDocumentDefinition = new {
      id = "MARK",
      firstName = "Mark",
      lastName = "Doe",
      addressLine = "123 Main Street",
      city = "Brooklyn",
      state = "New York",
      zip = "11229",
   }; 
	
   Document unindexedDocument = await client
      .CreateDocumentAsync("dbs/mydb/colls/manualindexing", unindexedDocumentDefinition);
  
   // Add another document (request indexing)
   dynamic indexedDocumentDefinition = new {
      id = "JANE",
      firstName = "Jane",
      lastName = "Doe",
      addressLine = "123 Main Street",
      city = "Brooklyn",
      state = "New York",
      zip = "11229",
   };
	
   Document indexedDocument = await client.CreateDocumentAsync
      ("dbs/mydb/colls/manualindexing", indexedDocumentDefinition, new RequestOptions {
      IndexingDirective = IndexingDirective.Include });

   //Unindexed document won't get returned when querying on non-ID (or selflink) property

   var doeDocs = client.CreateDocumentQuery("dbs/mydb/colls/manualindexing",
      "SELECT * FROM c WHERE c.lastName = 'Doe'").ToList();
   Console.WriteLine("Documents WHERE lastName = 'Doe': {0}", doeDocs.Count);
	
   // Unindexed document will get returned when using no WHERE clause
	
   var allDocs = client.CreateDocumentQuery("dbs/mydb/colls/manualindexing",
      "SELECT * FROM c").ToList();
   Console.WriteLine("All documents: {0}", allDocs.Count);
	
   // Unindexed document will get returned when querying by ID (or self-link) property
	
   Document markDoc = client
      .CreateDocumentQuery("dbs/mydb/colls/manualindexing",
      "SELECT * FROM c WHERE c.id = 'MARK'")
      .AsEnumerable().FirstOrDefault();
   Console.WriteLine("Unindexed document self-link: {0}", markDoc.SelfLink);
   await client.DeleteDocumentCollectionAsync("dbs/mydb/colls/manualindexing");
}

步驟 2 - 現在我們將再次建立與之前相同的兩個文件。這次我們將不對 Mark 的文件提供任何特殊的請求選項,因為根據集合的索引策略,此文件將不會被索引。

步驟 3 - 現在,當我們新增 Mark 的第二個文件時,我們使用 RequestOptions 和 IndexingDirective.Include 來告訴 DocumentDB 它應該索引此文件,這將覆蓋集合的索引策略(該策略指出不應索引此文件)。

最後,我們對這兩個文件有不同型別的查詢。

步驟 4 - 讓我們從 CreateDocumentClient 呼叫 ManualIndexing 任務。

private static async Task CreateDocumentClient() {
   // Create a new instance of the DocumentClient 
   using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
      await ManualIndexing(client); 
   } 
}

編譯並執行上述程式碼後,您將收到以下輸出。

**** Manual Indexing **** 
Documents WHERE lastName = 'Upston': 1 
All documents: 2 
Unindexed document self-link: dbs/kV5oAA==/colls/kV5oANHJPgE=/docs/kV5oANHJPgEBA 
AAAAAAAAA==/

同樣,查詢僅返回兩個文件中的一個,但這次它返回 Jane Doe,這是我們明確要求建立索引的。但與之前一樣,不帶 WHERE 子句的查詢將檢索集合中的所有文件,包括 Mark 的未建立索引的文件。我們還可以透過其 ID 查詢未建立索引的文件,DocumentDB 會返回它,即使它未建立索引。

廣告

© . All rights reserved.