DocumentDB - Indicizzazione dei record

Per impostazione predefinita, DocumentDB indicizza automaticamente ogni proprietà in un documento non appena il documento viene aggiunto al database. Tuttavia, puoi assumere il controllo e ottimizzare i tuoi criteri di indicizzazione che riducono il sovraccarico di archiviazione ed elaborazione quando sono presenti documenti e / o proprietà specifici che non devono mai essere indicizzati.

Il criterio di indicizzazione predefinito che indica a DocumentDB di indicizzare automaticamente ogni proprietà è adatto a molti scenari comuni. Ma puoi anche implementare una policy personalizzata che eserciti un controllo preciso su ciò che viene indicizzato e cosa no e altre funzionalità per quanto riguarda l'indicizzazione.

DocumentDB supporta i seguenti tipi di indicizzazione:

  • Hash
  • Range

Hash

L'indice hash consente una query efficiente per l'uguaglianza, ovvero durante la ricerca di documenti in cui una data proprietà è uguale a un valore esatto, piuttosto che corrispondere a un intervallo di valori come minore di, maggiore di o compreso tra.

È possibile eseguire query di intervallo con un indice hash, ma DocumentDB non sarà in grado di utilizzare l'indice hash per trovare i documenti corrispondenti e dovrà invece eseguire la scansione sequenziale di ogni documento per determinare se deve essere selezionato dalla query di intervallo.

Non sarai in grado di ordinare i tuoi documenti con una clausola ORDER BY su una proprietà che ha solo un indice hash.

Gamma

Indice di intervallo definito per la proprietà, DocumentDB consente di eseguire query in modo efficiente per i documenti rispetto a un intervallo di valori. Consente inoltre di ordinare i risultati della query su quella proprietà, utilizzando ORDER BY.

DocumentDB consente di definire sia un hash che un indice di intervallo su una o tutte le proprietà, il che consente query efficienti di uguaglianza e intervallo, nonché ORDER BY.

Politica di indicizzazione

Ogni raccolta ha una politica di indicizzazione che determina quali tipi di indici vengono utilizzati per numeri e stringhe in ogni proprietà di ogni documento.

  • Puoi anche controllare se i documenti devono essere indicizzati automaticamente quando vengono aggiunti alla raccolta.

  • L'indicizzazione automatica è abilitata per impostazione predefinita, ma è possibile ignorare tale comportamento quando si aggiunge un documento, dicendo a DocumentDB di non indicizzare quel particolare documento.

  • È possibile disabilitare l'indicizzazione automatica in modo che, per impostazione predefinita, i documenti non vengano indicizzati quando vengono aggiunti alla raccolta. Allo stesso modo, puoi sovrascriverlo a livello di documento e istruire DocumentDB a indicizzare un particolare documento quando lo aggiungi alla raccolta. Questo è noto come indicizzazione manuale.

Includi / escludi indicizzazione

Un criterio di indicizzazione può anche definire il percorso oi percorsi da includere o escludere dall'indice. Ciò è utile se sai che ci sono alcune parti di un documento su cui non interroghi mai e certe parti che fai.

In questi casi, è possibile ridurre il sovraccarico di indicizzazione dicendo a DocumentDB di indicizzare solo quelle parti particolari di ogni documento aggiunto alla raccolta.

Indicizzazione automatica

Diamo un'occhiata a un semplice esempio di indicizzazione automatica.

Step 1 - Per prima cosa creiamo una raccolta chiamata autoindicizzazione e senza fornire esplicitamente una politica, questa raccolta utilizza la politica di indicizzazione predefinita, il che significa che l'indicizzazione automatica è abilitata su questa raccolta.

Qui stiamo usando il routing basato sull'ID per l'auto-collegamento del database, quindi non abbiamo bisogno di conoscere il suo ID risorsa o interrogarlo prima di creare la raccolta. Possiamo semplicemente usare l'ID del database, che è mydb.

Step 2 - Adesso creiamo due documenti, entrambi con il cognome 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");
}

Questo primo, per Mark Upston, viene aggiunto alla raccolta e viene quindi immediatamente indicizzato automaticamente in base alla politica di indicizzazione predefinita.

Ma quando viene aggiunto il secondo documento per Mark Upston, abbiamo passato le opzioni di richiesta con IndexingDirective.Exclude che indica esplicitamente a DocumentDB di non indicizzare questo documento, nonostante la politica di indicizzazione della raccolta.

Abbiamo diversi tipi di query per entrambi i documenti alla fine.

Step 3 - Chiamiamo l'attività AutomaticIndexing da 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); 
   } 
}

Quando il codice precedente viene compilato ed eseguito, riceverai il seguente output.

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

Come puoi vedere, abbiamo due di questi documenti, ma la query restituisce solo quello per Mark perché quello per Mark non è indicizzato. Se interroghiamo di nuovo, senza una clausola WHERE per recuperare tutti i documenti nella raccolta, allora otteniamo un set di risultati con entrambi i documenti e questo perché i documenti non indicizzati vengono sempre restituiti da query che non hanno clausola WHERE.

Possiamo anche recuperare documenti non indicizzati tramite il loro ID o collegamento automatico. Quindi, quando interroghiamo il documento di Mark tramite il suo ID, MARK, vediamo che DocumentDB restituisce il documento anche se non è indicizzato nella raccolta.

Indicizzazione manuale

Diamo un'occhiata a un semplice esempio di indicizzazione manuale sovrascrivendo l'indicizzazione automatica.

Step 1- Per prima cosa creeremo una raccolta chiamataindicizzazione manuale e sovrascriveremo la politica predefinita disabilitando esplicitamente l'indicizzazione automatica. Ciò significa che, a meno che non venga richiesto diversamente, i nuovi documenti aggiunti a questa raccolta non verranno indicizzati.

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- Ora creeremo di nuovo gli stessi due documenti di prima. Questa volta non forniremo alcuna opzione di richiesta speciale per il documento di Mark, a causa della politica di indicizzazione della raccolta, questo documento non verrà indicizzato.

Step 3 - Ora, quando aggiungiamo il secondo documento per Mark, usiamo RequestOptions con IndexingDirective.Include per dire a DocumentDB che dovrebbe indicizzare questo documento, il che sovrascrive la politica di indicizzazione della raccolta che dice che non dovrebbe.

Abbiamo diversi tipi di query per entrambi i documenti alla fine.

Step 4 - Chiamiamo l'attività ManualIndexing da 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); 
   } 
}

Quando il codice precedente viene compilato ed eseguito, riceverai il seguente output.

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

Anche in questo caso, la query restituisce solo uno dei due documenti, ma questa volta restituisce Jane Doe, di cui abbiamo richiesto esplicitamente l'indicizzazione. Ma ancora come prima, l'interrogazione senza una clausola WHERE recupera tutti i documenti nella raccolta, incluso il documento non indicizzato per Mark. Possiamo anche interrogare il documento non indicizzato tramite il suo ID, che DocumentDB restituisce anche se non è indicizzato.