DocumentDB - indeksowanie rekordów

Domyślnie DocumentDB automatycznie indeksuje każdą właściwość w dokumencie, gdy tylko dokument zostanie dodany do bazy danych. Możesz jednak przejąć kontrolę i dostroić własne zasady indeksowania, które zmniejszają obciążenie związane z przechowywaniem i przetwarzaniem, gdy istnieją określone dokumenty i / lub właściwości, które nigdy nie wymagają indeksowania.

Domyślna zasada indeksowania, która nakazuje usłudze DocumentDB automatyczne indeksowanie każdej właściwości, jest odpowiednia dla wielu typowych scenariuszy. Ale możesz również wdrożyć niestandardowe zasady, które dokładnie kontrolują to, co jest indeksowane, a co nie, oraz inne funkcje związane z indeksowaniem.

DocumentDB obsługuje następujące typy indeksowania -

  • Hash
  • Range

Haszysz

Hash index umożliwia wydajne sprawdzanie równości, tj. Podczas wyszukiwania dokumentów, w których dana właściwość jest równa dokładnej wartości, zamiast dopasowywania do zakresu wartości, takich jak mniej niż, większe niż lub pomiędzy.

Możesz wykonywać zapytania o zakres z indeksem skrótu, ale DocumentDB nie będzie w stanie użyć indeksu skrótu do znalezienia pasujących dokumentów i zamiast tego będzie musiał sekwencyjnie skanować każdy dokument, aby określić, czy powinien zostać wybrany przez zapytanie o zakres.

Nie będziesz w stanie sortować dokumentów za pomocą klauzuli ORDER BY we właściwości, która ma tylko indeks skrótu.

Zasięg

Indeks zakresu zdefiniowany dla właściwości, DocumentDB umożliwia wydajne wyszukiwanie dokumentów w oparciu o zakres wartości. Pozwala również na sortowanie wyników zapytań dotyczących tej właściwości za pomocą ORDER BY.

DocumentDB umożliwia zdefiniowanie zarówno skrótu, jak i indeksu zakresu dla dowolnej lub wszystkich właściwości, co umożliwia wydajne zapytania o równość i zakres, a także ORDER BY.

Zasady indeksowania

Każda kolekcja ma zasady indeksowania, które dyktują, jakie typy indeksów są używane dla liczb i ciągów znaków w każdej właściwości każdego dokumentu.

  • Możesz także kontrolować, czy dokumenty mają być indeksowane automatycznie, gdy są dodawane do kolekcji.

  • Automatyczne indeksowanie jest domyślnie włączone, ale można zmienić to zachowanie podczas dodawania dokumentu, informując DocumentDB, aby nie indeksował tego konkretnego dokumentu.

  • Można wyłączyć automatyczne indeksowanie, aby domyślnie dokumenty nie były indeksowane po dodaniu do kolekcji. Podobnie możesz to zmienić na poziomie dokumentu i poinstruować DocumentDB, aby indeksował określony dokument podczas dodawania go do kolekcji. Nazywa się to ręcznym indeksowaniem.

Uwzględnij / wyklucz indeksowanie

Zasady indeksowania mogą również określać, która ścieżka lub ścieżki powinny być uwzględnione lub wykluczone z indeksu. Jest to przydatne, jeśli wiesz, że istnieją pewne części dokumentu, w odniesieniu do których nigdy nie wykonujesz zapytań, i pewne części, które robisz.

W takich przypadkach można zmniejszyć obciążenie związane z indeksowaniem, nakazując usłudze DocumentDB indeksowanie tylko tych określonych części każdego dokumentu dodanego do kolekcji.

Automatyczne indeksowanie

Spójrzmy na prosty przykład automatycznego indeksowania.

Step 1 - Najpierw tworzymy kolekcję o nazwie autoindexing i bez jawnego dostarczania zasad, ta kolekcja korzysta z domyślnych zasad indeksowania, co oznacza, że ​​automatyczne indeksowanie jest włączone w tej kolekcji.

W tym przypadku używamy routingu opartego na identyfikatorach dla samodzielnego łączenia bazy danych, więc nie musimy znać jego identyfikatora zasobu ani zapytać o niego przed utworzeniem kolekcji. Możemy po prostu użyć identyfikatora bazy danych, którym jest mydb.

Step 2 - Teraz utwórzmy dwa dokumenty, oba z nazwiskiem 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");
}

Ten pierwszy, dla Mark Upston, jest dodawany do kolekcji, a następnie jest natychmiast indeksowany automatycznie na podstawie domyślnych zasad indeksowania.

Ale po dodaniu drugiego dokumentu dla Mark Upston przekazaliśmy opcje żądania za pomocą IndexingDirective.Exclude, która wyraźnie instruuje DocumentDB, aby nie indeksować tego dokumentu, pomimo zasad indeksowania kolekcji.

Na końcu mamy różne rodzaje zapytań do obu dokumentów.

Step 3 - Wywołajmy zadanie AutomaticIndexing z 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); 
   } 
}

Gdy powyższy kod zostanie skompilowany i wykonany, otrzymasz następujące dane wyjściowe.

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

Jak widać, mamy dwa takie dokumenty, ale zapytanie zwraca tylko ten dotyczący Marka, ponieważ ten dotyczący Marka nie jest indeksowany. Jeśli ponownie zapytamy, bez klauzuli WHERE w celu pobrania wszystkich dokumentów w kolekcji, otrzymamy zestaw wyników z obydwoma dokumentami, a dzieje się tak, ponieważ niezindeksowane dokumenty są zawsze zwracane przez zapytania, które nie mają klauzuli WHERE.

Możemy również odzyskać niezindeksowane dokumenty za pomocą ich identyfikatora lub linku własnego. Kiedy więc wyszukujemy dokument Marka, używając jego identyfikatora MARK, widzimy, że DocumentDB zwraca dokument, mimo że nie jest indeksowany w kolekcji.

Indeksowanie ręczne

Przyjrzyjmy się prostemu przykładowi ręcznego indeksowania przez zastąpienie automatycznego indeksowania.

Step 1- Najpierw utworzymy kolekcję o nazwie manualindexing i zastąpimy domyślne zasady, jawnie wyłączając automatyczne indeksowanie. Oznacza to, że o ile nie zażądamy inaczej, nowe dokumenty dodawane do tej kolekcji nie będą indeksowane.

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- Teraz ponownie utworzymy te same dwa dokumenty, co poprzednio. Tym razem nie dostarczymy żadnych specjalnych opcji żądania dla dokumentu Marka, ponieważ z powodu zasad indeksowania kolekcji ten dokument nie zostanie zindeksowany.

Step 3 - Teraz, kiedy dodajemy drugi dokument dla Mark, używamy RequestOptions z IndexingDirective.Include, aby poinformować DocumentDB, że powinien indeksować ten dokument, co zastępuje politykę indeksowania kolekcji, która mówi, że nie powinna.

Na końcu mamy różne rodzaje zapytań do obu dokumentów.

Step 4 - Nazwijmy zadanie ManualIndexing z 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); 
   } 
}

Kiedy powyższy kod zostanie skompilowany i wykonany, otrzymasz następujące dane wyjściowe.

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

Ponownie zapytanie zwraca tylko jeden z dwóch dokumentów, ale tym razem zwraca Jane Doe, o której indeksowanie wyraźnie zażądaliśmy. Ale znowu, jak poprzednio, zapytanie bez klauzuli WHERE powoduje pobranie wszystkich dokumentów w kolekcji, w tym niezindeksowanego dokumentu dla Marka. Możemy również zapytać o niezindeksowany dokument według jego identyfikatora, który DocumentDB zwraca, mimo że nie jest indeksowany.