DocumentDB - Bản ghi chỉ mục

Theo mặc định, DocumentDB tự động lập chỉ mục mọi thuộc tính trong tài liệu ngay sau khi tài liệu được thêm vào cơ sở dữ liệu. Tuy nhiên, bạn có thể kiểm soát và tinh chỉnh chính sách lập chỉ mục của riêng mình để giảm chi phí lưu trữ và xử lý khi có các tài liệu và / hoặc thuộc tính cụ thể không bao giờ cần được lập chỉ mục.

Chính sách lập chỉ mục mặc định yêu cầu DocumentDB tự động lập chỉ mục mọi thuộc tính phù hợp với nhiều trường hợp phổ biến. Nhưng bạn cũng có thể triển khai chính sách tùy chỉnh thực hiện quyền kiểm soát tốt đối với chính xác những gì được lập chỉ mục và những gì không và chức năng khác liên quan đến lập chỉ mục.

DocumentDB hỗ trợ các kiểu lập chỉ mục sau:

  • Hash
  • Range

Băm

Chỉ mục băm cho phép truy vấn hiệu quả về bình đẳng, tức là trong khi tìm kiếm tài liệu trong đó một thuộc tính nhất định bằng một giá trị chính xác, thay vì khớp trên một phạm vi giá trị như nhỏ hơn, lớn hơn hoặc giữa.

Bạn có thể thực hiện các truy vấn phạm vi với chỉ mục băm, nhưng DocumentDB sẽ không thể sử dụng chỉ mục băm để tìm các tài liệu phù hợp và thay vào đó sẽ cần quét tuần tự từng tài liệu để xác định xem nó có nên được chọn bởi truy vấn phạm vi hay không.

Bạn sẽ không thể sắp xếp tài liệu của mình bằng mệnh đề ORDER BY trên thuộc tính chỉ có chỉ mục băm.

Phạm vi

Chỉ mục phạm vi được xác định cho thuộc tính, DocumentDB cho phép truy vấn hiệu quả các tài liệu dựa trên phạm vi giá trị. Nó cũng cho phép bạn sắp xếp các kết quả truy vấn trên thuộc tính đó, sử dụng ORDER BY.

DocumentDB cho phép bạn xác định cả chỉ số băm và chỉ mục phạm vi trên bất kỳ hoặc tất cả các thuộc tính, cho phép truy vấn bình đẳng và phạm vi hiệu quả, cũng như ORDER BY.

Chính sách lập chỉ mục

Mọi tập hợp đều có chính sách lập chỉ mục quy định loại chỉ mục nào được sử dụng cho các số và chuỗi trong mọi thuộc tính của mọi tài liệu.

  • Bạn cũng có thể kiểm soát việc tài liệu có được tự động lập chỉ mục khi chúng được thêm vào bộ sưu tập hay không.

  • Lập chỉ mục tự động được bật theo mặc định, nhưng bạn có thể ghi đè hành vi đó khi thêm tài liệu, yêu cầu DocumentDB không lập chỉ mục tài liệu cụ thể đó.

  • Bạn có thể tắt lập chỉ mục tự động để theo mặc định, tài liệu không được lập chỉ mục khi được thêm vào bộ sưu tập. Tương tự, bạn có thể ghi đè điều này ở cấp tài liệu và hướng dẫn DocumentDB lập chỉ mục một tài liệu cụ thể khi thêm nó vào bộ sưu tập. Đây được gọi là lập chỉ mục thủ công.

Bao gồm / Loại trừ Lập chỉ mục

Chính sách lập chỉ mục cũng có thể xác định đường dẫn hoặc đường dẫn nào nên được bao gồm hoặc loại trừ khỏi chỉ mục. Điều này hữu ích nếu bạn biết rằng có một số phần nhất định của tài liệu mà bạn không bao giờ truy vấn và một số phần nhất định mà bạn thực hiện.

Trong những trường hợp này, bạn có thể giảm chi phí lập chỉ mục bằng cách yêu cầu DocumentDB chỉ lập chỉ mục những phần cụ thể của mỗi tài liệu được thêm vào bộ sưu tập.

Lập chỉ mục tự động

Hãy xem một ví dụ đơn giản về lập chỉ mục tự động.

Step 1 - Đầu tiên, chúng tôi tạo một bộ sưu tập được gọi là autoindexing và không cung cấp chính sách rõ ràng, bộ sưu tập này sử dụng chính sách lập chỉ mục mặc định, có nghĩa là tính năng lập chỉ mục tự động được bật trên bộ sưu tập này.

Ở đây chúng tôi đang sử dụng định tuyến dựa trên ID cho cơ sở dữ liệu tự liên kết nên chúng tôi không cần biết ID tài nguyên của nó hoặc truy vấn cho nó trước khi tạo bộ sưu tập. Chúng tôi chỉ có thể sử dụng ID cơ sở dữ liệu, đó là mydb.

Step 2 - Bây giờ chúng ta hãy tạo hai tài liệu, cả hai đều có họ là 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");
}

Cái đầu tiên này, đối với Mark Upston, được thêm vào bộ sưu tập và sau đó ngay lập tức được lập chỉ mục tự động dựa trên chính sách lập chỉ mục mặc định.

Nhưng khi tài liệu thứ hai cho Mark Upston được thêm vào, chúng tôi đã chuyển các tùy chọn yêu cầu với IndexingDirective.Exclude hướng dẫn rõ ràng DocumentDB không lập chỉ mục tài liệu này, bất chấp chính sách lập chỉ mục của bộ sưu tập.

Chúng tôi có các loại truy vấn khác nhau cho cả hai tài liệu ở cuối.

Step 3 - Hãy gọi tác vụ AutomaticIndexing từ CreateDocumentClient.

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

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ nhận được kết quả sau.

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

Như bạn có thể thấy, chúng tôi có hai tài liệu như vậy, nhưng truy vấn chỉ trả về một tài liệu cho Mark vì tài liệu cho Mark không được lập chỉ mục. Nếu chúng ta truy vấn lại mà không có mệnh đề WHERE để truy xuất tất cả các tài liệu trong bộ sưu tập, thì chúng tôi sẽ nhận được một tập hợp kết quả với cả hai tài liệu và điều này là do các tài liệu chưa lập chỉ mục luôn được trả về bởi các truy vấn không có mệnh đề WHERE.

Chúng tôi cũng có thể truy xuất các tài liệu chưa lập chỉ mục bằng ID hoặc liên kết tự của chúng. Vì vậy, khi chúng tôi truy vấn tài liệu của Mark theo ID của anh ấy, MARK, chúng tôi thấy rằng DocumentDB trả về tài liệu mặc dù nó không được lập chỉ mục trong bộ sưu tập.

Lập chỉ mục thủ công

Hãy xem một ví dụ đơn giản về lập chỉ mục thủ công bằng cách ghi đè lập chỉ mục tự động.

Step 1- Đầu tiên, chúng tôi sẽ tạo một bộ sưu tập được gọi là lập chỉ mục thủ công và ghi đè chính sách mặc định bằng cách tắt lập chỉ mục tự động một cách rõ ràng. Điều này có nghĩa là, trừ khi chúng tôi yêu cầu khác, các tài liệu mới được thêm vào bộ sưu tập này sẽ không được lập chỉ mục.

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");
}

Step 2- Bây giờ chúng ta sẽ tạo lại hai tài liệu giống như trước. Chúng tôi sẽ không cung cấp bất kỳ tùy chọn yêu cầu đặc biệt nào cho tài liệu của Mark lần này, vì chính sách lập chỉ mục của bộ sưu tập, tài liệu này sẽ không được lập chỉ mục.

Step 3 - Bây giờ khi chúng tôi thêm tài liệu thứ hai cho Mark, chúng tôi sử dụng RequestOptions với IndexingDirective.Include để nói với DocumentDB rằng nó nên lập chỉ mục tài liệu này, điều này ghi đè chính sách lập chỉ mục của bộ sưu tập nói rằng không nên.

Chúng tôi có các loại truy vấn khác nhau cho cả hai tài liệu ở cuối.

Step 4 - Hãy gọi tác vụ ManualIndexing từ CreateDocumentClient.

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

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ nhận được kết quả sau.

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

Một lần nữa, truy vấn chỉ trả về một trong hai tài liệu, nhưng lần này, nó trả về Jane Doe, mà chúng tôi đã yêu cầu lập chỉ mục một cách rõ ràng. Nhưng một lần nữa như trước, truy vấn mà không có mệnh đề WHERE sẽ truy xuất tất cả các tài liệu trong bộ sưu tập, bao gồm cả tài liệu chưa lập chỉ mục cho Mark. Chúng tôi cũng có thể truy vấn tài liệu chưa lập chỉ mục bằng ID của nó, DocumentDB trả về mặc dù nó không được lập chỉ mục.