Учебники

DocumentDB — индексирование записей

По умолчанию DocumentDB автоматически индексирует каждое свойство в документе, как только документ добавляется в базу данных. Однако вы можете взять под свой контроль и точно настроить собственную политику индексации, которая уменьшает накладные расходы на хранение и обработку, когда есть определенные документы и / или свойства, которые никогда не нужно индексировать.

Политика индексации по умолчанию, которая указывает DocumentDB автоматически индексировать каждое свойство, подходит для многих распространенных сценариев. Но вы также можете реализовать собственную политику, которая точно контролирует, что именно индексируется, а что нет, и другие функции в отношении индексации.

DocumentDB поддерживает следующие типы индексации —

  • гашиш
  • Спектр

гашиш

Индекс хэша позволяет эффективно запрашивать равенство, т. Е. При поиске документов, в которых заданное свойство равно точному значению, а не при сопоставлении с диапазоном значений, таких как меньше, больше или между.

Вы можете выполнять запросы диапазона с хэш-индексом, но DocumentDB не сможет использовать хэш-индекс для поиска подходящих документов, и вместо этого ему придется последовательно сканировать каждый документ, чтобы определить, должен ли он быть выбран с помощью запроса диапазона.

Вы не сможете отсортировать документы с помощью предложения ORDER BY для свойства, имеющего только хэш-индекс.

Спектр

Индекс диапазона, определенный для свойства DocumentDB, позволяет эффективно запрашивать документы по диапазону значений. Это также позволяет вам сортировать результаты запроса по этому свойству, используя ORDER BY.

DocumentDB позволяет вам определять как хэш, так и индекс диапазона для любого или всех свойств, что позволяет эффективно выполнять запросы на равенство и диапазон, а также ORDER BY.

Политика индексации

Каждая коллекция имеет политику индексации, которая определяет, какие типы индексов используются для чисел и строк в каждом свойстве каждого документа.

  • Вы также можете контролировать, будут ли документы проиндексированы автоматически при их добавлении в коллекцию.

  • Автоматическое индексирование включено по умолчанию, но вы можете изменить это поведение при добавлении документа, сказав DocumentDB не индексировать этот конкретный документ.

  • Вы можете отключить автоматическую индексацию, чтобы по умолчанию документы не индексировались при добавлении в коллекцию. Точно так же вы можете переопределить это на уровне документа и дать указание DocumentDB индексировать конкретный документ при добавлении его в коллекцию. Это известно как ручное индексирование.

Вы также можете контролировать, будут ли документы проиндексированы автоматически при их добавлении в коллекцию.

Автоматическое индексирование включено по умолчанию, но вы можете изменить это поведение при добавлении документа, сказав DocumentDB не индексировать этот конкретный документ.

Вы можете отключить автоматическую индексацию, чтобы по умолчанию документы не индексировались при добавлении в коллекцию. Точно так же вы можете переопределить это на уровне документа и дать указание DocumentDB индексировать конкретный документ при добавлении его в коллекцию. Это известно как ручное индексирование.

Включить / исключить индексирование

Политика индексирования также может определять, какой путь или пути должны быть включены или исключены из индекса. Это полезно, если вы знаете, что есть определенные части документа, к которым вы никогда не обращаетесь, и определенные части, которые вы делаете.

В этих случаях вы можете уменьшить накладные расходы на индексирование, сказав DocumentDB индексировать только те конкретные части каждого документа, добавленные в коллекцию.

Автоматическая индексация

Давайте рассмотрим простой пример автоматической индексации.

Шаг 1. Сначала мы создаем коллекцию с именем autoindexing, и без явного указания политики эта коллекция использует политику индексации по умолчанию, что означает, что для этой коллекции включена автоматическая индексация.

Здесь мы используем маршрутизацию на основе идентификатора для самоопределения базы данных, поэтому нам не нужно знать его идентификатор ресурса или запрашивать его перед созданием коллекции. Мы можем просто использовать идентификатор базы данных, который является 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");
}

Этот первый, для Марка Апстона, добавляется в коллекцию, а затем сразу же индексируется автоматически на основе политики индексации по умолчанию.

Но когда был добавлен второй документ для Марка Апстона, мы передали параметры запроса с помощью IndexingDirective.Exclude, которое явно указывает DocumentDB не индексировать этот документ, несмотря на политику индексации коллекции.

У нас есть разные типы запросов для обоих документов в конце.

Шаг 3 — Давайте вызовем задачу AutomaticIndexing из 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); 
   } 
}

Когда приведенный выше код скомпилирован и выполнен, вы получите следующий вывод.

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

Как видите, у нас есть два таких документа, но запрос возвращает только один для Марка, потому что один для Марка не проиндексирован. Если мы запросим снова, без предложения WHERE, чтобы получить все документы в коллекции, то мы получим набор результатов с обоими документами, и это потому, что неиндексированные документы всегда возвращаются запросами, у которых нет предложения WHERE.

Мы также можем получить неиндексированные документы по их идентификатору или по собственной ссылке. Поэтому, когда мы запрашиваем документ Марка по его идентификатору, 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 — Теперь мы снова создадим те же два документа, что и раньше. На этот раз мы не будем предоставлять никаких специальных параметров запроса для документа Марка, поскольку из-за политики индексирования коллекции этот документ не будет проиндексирован.

Шаг 3 — Теперь, когда мы добавляем второй документ для Mark, мы используем RequestOptions с IndexingDirective.Include, чтобы сообщить DocumentDB, что он должен индексировать этот документ, который переопределяет политику индексации коллекции, которая говорит, что это не должно.

У нас есть разные типы запросов для обоих документов в конце.

Шаг 4 — Давайте вызовем задачу ManualIndexing из 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); 
   } 
}

Когда приведенный выше код скомпилирован и выполнен, вы получите следующий вывод.

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

Опять же, запрос возвращает только один из двух документов, но на этот раз он возвращает Джейн Доу, которую мы явно просили проиндексировать. Но опять же, как и раньше, запрос без предложения WHERE возвращает все документы в коллекции, включая неиндексированный документ для Марка. Мы также можем запросить неиндексированный документ по его идентификатору, который возвращает DocumentDB, даже если он не проиндексирован.