Condividi tramite


Gestire l'indicizzazione in Azure DocumentDB

Gli indici sono strutture che migliorano la velocità di recupero dei dati fornendo un accesso rapido ai campi in una raccolta. Funzionano creando un set ordinato di puntatori ai dati, spesso in base ai campi chiave. Azure DocumentDB utilizza indici in più contesti, tra cui l'ottimizzazione delle query, i vincoli univoci e il partizionamento orizzontale dei dati.

Importante

Il campo "_id" è l'unico campo indicizzato per impostazione predefinita e le dimensioni massime del campo possono essere 2 KB. È consigliabile aggiungere altri indici in base a filtri e predicati di query per ottimizzare le prestazioni.

Tipi di indice

Per semplicità, si consideri un esempio di applicazione blog con la configurazione seguente:

  • Nome del database: cosmicworks
  • Nome raccolta: products

Questa applicazione di esempio archivia gli articoli come documenti con la struttura seguente. Tutto l'esempio citato utilizza ulteriormente la struttura di questa raccolta.

{
  "_id": ObjectId("617a34e7a867530bff1b2346"),
  "title": "Azure DocumentDB - A Game Changer",
  "content": "Azure DocumentDB is a globally distributed, multi-model database service.",
  "author": {lastName: "Doe", firstName: "John"},
  "category": "Technology",
  "launchDate": ISODate("2024-06-24T10:08:20.000Z"),
  "published": true
}

Indici a campo singolo

Gli indici di campo singolo archiviano le informazioni da un singolo campo in una raccolta. L'ordine dell'indice di campo singolo non è rilevante. _id il campo rimane indicizzato per impostazione predefinita.

Azure DocumentDB supporta la creazione di un indice nelle seguenti condizioni.

  • Campi documento di primo livello.
  • Documento incorporato.
  • Campi all'interno del documento annidato.

Il comando seguente crea un singolo indice di campo nel campo author e il comando seguente lo crea in un campo firstNameincorporato.

use cosmicworks

db.products.createIndex({"author": 1})

// indexing embedded property
db.products.createIndex({"author.firstName": -1})

Una query può usare più indici di campo singoli, se disponibili.

Annotazioni

Azure DocumentDB consente di creare un massimo di 64 indici in una raccolta. A seconda del livello, è possibile pianificare l'estensione fino a 300 indici su richiesta.

Indici composti

Gli indici composti migliorano le prestazioni del database consentendo query e ordinamento efficienti in base a più campi all'interno dei documenti. Questa ottimizzazione riduce la necessità di analizzare intere raccolte, velocizzando il recupero dei dati e l'organizzazione.

Il comando seguente crea un indice composto nei campi author e launchDate in ordine di ordinamento opposto.

use cosmicworks

db.products.createIndex({"author":1, "launchDate":-1})

Order dei campi influiscono sulla selettività o sull'utilizzo dell'indice. La find query non utilizzerebbe l'indice creato.

use cosmicworks

db.products.find({"launchDate": {$gt: ISODate("2024-06-01T00:00:00.000Z")}})

Limitazioni

  • Massimo 32 campi\percorsi all'interno di un indice composto.

Indici parziali

Indici con un filtro di query associato che descrive quando generare un termine nell'indice.

use cosmicworks

db.products.createIndex (
   { "author": 1, "launchDate": 1 },
   { partialFilterExpression: { "launchDate": { $gt: ISODate("2024-06-24T10:08:20.000Z") } } }
)

Limitazioni

  • Gli indici parziali non supportano ORDER BY o UNIQUE a meno che il filtro non sia qualificato.

Indici di testo

Gli indici di testo sono strutture di dati speciali che ottimizzano le query basate su testo, rendendole più veloci ed efficienti.

Usare il createIndex metodo con l'opzione text per creare un indice di testo nel title campo.

use cosmicworks;

db.products.createIndex({ title: "text" })

Annotazioni

Sebbene sia possibile definire un solo indice di testo per ogni raccolta, Azure DocumentDB consente di creare indici di testo in combinazione di più campi per consentire di eseguire ricerche di testo in campi diversi nei documenti.

Configurare le opzioni per l'indice di testo

Gli indici di testo in Azure DocumentDB includono diverse opzioni per personalizzare il comportamento. Ad esempio, è possibile specificare la lingua per l'analisi del testo, impostare pesi per classificare in ordine di priorità determinati campi e configurare ricerche senza distinzione tra maiuscole e minuscole. Ecco un esempio di creazione di un indice di testo con opzioni:

  • Creare un indice per supportare la ricerca in entrambi i campi title e content con supporto per la lingua inglese. Assegnare inoltre pesi più elevati al title campo per assegnargli la priorità nei risultati della ricerca.

    use cosmicworks
    
    db.products.createIndex(
        { title: "text", content: "text" },
        { default_language: "english", weights: { title: 10, content: 5 }, caseSensitive: false }
    )
    

Annotazioni

Quando un client esegue una query di ricerca di testo con il termine "DocumentDB", il punteggio per ogni documento nella raccolta verrà calcolato in base alla presenza e alla frequenza del termine nei campi "title" e "content", con maggiore importanza assegnata al campo "title" a causa del peso maggiore.

Eseguire una ricerca di testo usando un indice di testo

Dopo aver creato l'indice di testo, è possibile eseguire ricerche di testo usando l'operatore "text" nelle query. L'operatore di testo prende una stringa di ricerca e la confronta con l'indice di testo per trovare i documenti pertinenti.

  • Eseguire una ricerca di testo per la frase DocumentDB.

    use cosmicworks
    
    db.products.find(
      { $text: { $search: "DocumentDB" } }
    )
    
  • Facoltativamente, usare l'operatore $meta di proiezione insieme al textScore campo in una query per visualizzare il peso

    use cosmicworks
    
    db.products.find(
    { $text: { $search: "DocumentDB" } },
    { score: { $meta: "textScore" } }
    )
    

Limitazioni

  • È possibile definire un solo indice di testo in una raccolta.
  • Le operazioni di ordinamento non possono usare l'ordinamento dell'indice di testo in MongoDB.
  • Hint() non è supportato in combinazione con una query usando l'espressione $text.
  • Gli indici di testo possono essere relativamente grandi, consumando spazio di archiviazione significativo rispetto ad altri tipi di indice.

Indici WildCard

Indice su un singolo campo, indicizza tutti i percorsi sotto field, escludendo gli altri campi che si trovano allo stesso livello. Ad esempio, per il documento di esempio seguente

{
 "children":
    {
     "familyName": "Merriam",
     "pets": { "details": {“name”: "Goofy", ”age”: 3} }
   } 
}

Creazione di un indice in { "pets.$**": 1 }, crea l'indice per i dettagli e le proprietà del documento secondario, ma non crea un indice in "familyName".

Limitazioni

  • Gli indici wildcard non possono supportare indici univoci.
  • Gli indici con caratteri jolly non supportano il push down di ORDER BY a meno che il filtro non includa solo i percorsi presenti nel carattere jolly (poiché non indicizzano elementi non definiti)
  • Un indice con caratteri jolly composti può avere solo one carattere jolly e one o più termini di indice. { "pets.$**": 1, “familyName”: 1 }

Indici geospaziali

Gli indici geospaziali supportano query sui dati archiviati come oggetti GeoJSON o coppie di coordinate legacy. È possibile usare indici geospaziali per migliorare le prestazioni per le query sui dati geospaziali o per eseguire determinate query geospaziali.

Azure DocumentDB offre due tipi di indici geospaziali:

  • 2dsphere Indexes, che supporta le query che interpretano la geometria su una sfera.
  • Indici 2d, che supportano query che interpretano la geometria su una superficie piatta.

Indici bidimensionali

Gli indici 2d sono supportati solo con il formato legacy di coppia di coordinate per l'archiviazione di dati geospaziali.

Usare il createIndex metodo con l'opzione 2d per la creazione di un indice geospaziale nel location campo.

db.places.createIndex({ "location": "2d"});

Limitazioni

  • Solo one il campo di posizione può far parte dell'indice 2d e solo one altri campi non geospaziali possono far parte dell'indice compound 2ddb.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1 })

Indici 2dsphere

Gli indici 2dsphere supportano query geospaziali su una sfera simile alla terra. Può supportare sia oggetti GeoJSON che coppie di coordinate legacy. 2dSphere gli indici funzionano con lo stile GeoJSON di archiviazione dei dati, se vengono rilevati punti legacy, verrà convertito in punto GeoJSON.

Usare il createIndex metodo con l'opzione 2dsphere per la creazione di un indice geospaziale nel location campo.

db.places.createIndex({ "location": "2dsphere"});

2dsphere gli indici consentono di creare indici in più campi dati geospaziali e non geospaziali. db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1, ... "more non-geospatial-field": 1 / -1 })

Limitazioni

  • Un indice composto che usa un indice regolare e un indice geospaziale non è supportato. La creazione di uno degli indici geospaziali comporta errori.

    // Compound Regular & 2dsphere indexes are not supported yet
    db.collection.createIndex({a: 1, b: "2dsphere"})
    
    // Compound 2d indexes are not supported yet
    db.collection.createIndex({a: "2d", b: 1})
    
  • I poligoni con fori non funzionano. L'inserimento di un poligono con foro non è limitato, nonostante $geoWithin la query fallisca in alcuni scenari:

    1. Se la query stessa ha un poligono con fori

      coll.find(
        {
            "b": {
                "$geoWithin": {
                    "$geometry": {
                        "coordinates": [
                            [
                                [ 0, 0], [0, 10], [10, 10],[10,0],[0, 0]
                            ],
                            [
                                [5, 5], [8, 5], [ 8, 8], [ 5, 8], [ 5, 5]
                            ]
                        ],
                        "type": "Polygon"
                    }
                }
            }
        })
      
      // MongoServerError: $geoWithin currently doesn't support polygons with holes
      
    2. Se è presente un documento non filtrato con poligono con fori.

      [mongos] test> coll.find()
        [
          {
            _id: ObjectId("667bf7560b4f1a5a5d71effa"),
            b: {
              type: 'Polygon',
              coordinates: [
                [ [ 0, 0 ], [ 0, 10 ], [ 10, 10 ], [ 10, 0 ], [ 0, 0 ] ],
                [ [ 5, 5 ], [ 8, 5 ], [ 8, 8 ], [ 5, 8 ], [ 5, 5 ] ]
              ]
            }
          }
        ]
      // MongoServerError: $geoWithin currently doesn't support polygons with holes
      
    3. key il campo è obbligatorio durante l'uso di geoNear.

       [mongos] test> coll.aggregate([{ $geoNear: { $near: { "type": "Point", coordinates: [0, 0] } } }])
      
       // MongoServerError: $geoNear requires a 'key' option as a String
      

Passaggi successivi