Condividi tramite


Gestire l'indicizzazione nel vCore di Azure Cosmos DB for MongoDB

SI APPLICA A: MongoDB vCore

Gli indici sono strutture che migliorano la velocità di recupero dei dati fornendo l'accesso rapido ai campi in una raccolta. Funzionano creando un set ordinato di puntatori che rimandano ai dati, spesso in base ai campi chiave. Il vCore di Azure Cosmos DB for MongoDB usa indici in più contesti, tra cui l'analisi pushdown delle query, i vincoli univoci e il partizionamento orizzontale.

Importante

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

Tipi di indice

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

  • Nome del database: cosmicworks
  • Nome della raccolta: products

Questa applicazione di esempio archivia gli articoli come documenti con la struttura riportata di seguito. L'esempio citato sfrutta ulteriormente la struttura della raccolta.

{
  "_id": ObjectId("617a34e7a867530bff1b2346"),
  "title": "Azure Cosmos DB - A Game Changer",
  "content": "Azure Cosmos DB 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 di campo singolo

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

Il vCore di Azure Cosmos DB for MongoDB supporta gli indici e le seguenti proprietà di indice

  • Campi di primo livello del documento.
  • Documento incorporato.
  • Campi nel documento incorporato.

Il comando riportato di seguito crea un singolo indice di campo nel campo author e lo crea in un campo incorporato firstName.

use cosmicworks

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

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

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

Nota

Il vCore di Azure Cosmos DB for MongoDB consente di creare fino a 64 indici in una raccolta. A seconda del livello, si può pianificare l'estensione fino a 300 indici su richiesta.

Indici composti

Gli indici composti migliorano le prestazioni del database consentendo di rendere più efficienti le query e l'ordinamento tramite i campi multipli nei documenti. Questa ottimizzazione permette di non dover analizzare intere raccolte, velocizzando il recupero dati e l'organizzazione.

Il seguente comando crea un indice composto nei campi author e launchDate con un ordinamento opposto.

use cosmicworks

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

Order dei campi influiscono sul selezionamento o sull'utilizzo dell'indice. La query find non utilizza l'indice creato.

use cosmicworks

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

Limiti

  • Massimo 32 campi/percorsi in 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") } } }
)

Limiti

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

Indici di testo

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

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

use cosmicworks;

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

Nota

Sebbene sia possibile definire un solo indice di testo per ogni raccolta, Azure Cosmos DB per MongoDB vCore consente di creare indici di testo su una combinazione di più campi, per eseguire ricerche di testo in campi diversi nei documenti.

Configurare le opzioni per l'indice di testo

Gli indici di testo nel vCore di Azure Cosmos DB for MongoDB includono diverse opzioni per personalizzarne il comportamento. Ad esempio, è possibile specificare la lingua per l'analisi del testo, impostare la priorità di determinati campi e configurare le 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 nei campi title e content con supporto per la lingua inglese. Assegnare inoltre un indici di priorità più elevata al campo title per dargli 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 }
    )
    

Nota

Quando un utente esegue una query di ricerca di testo con il termine "Cosmos DB", 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 della priorità 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 text prende una stringa di ricerca e la confronta in base all'indice di testo per trovare i documenti pertinenti.

  • Eseguire una ricerca di testo per la frase Cosmos DB.

    use cosmicworks
    
    db.products.find(
      { $text: { $search: "Cosmos DB" } }
    )
    
  • Si può usare l'operatore $meta di proiezione insieme al textScore campo in una query per visualizzarne la priorità

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

Limiti

  • È possibile definire un solo indice di testo in una raccolta.
  • Gli indici di testo supportano ricerche di testo semplici, ma non offrono funzionalità di ricerca avanzate come le espressioni regolari.
  • Le operazioni di riordinamento non possono usare l'ordine dell'indice di testo in MongoDB.
  • Hint() non è supportato in combinazione con una query che usa l’espressione $text.
  • Gli indici di testo possono essere relativamente grandi, occupando spazio di archiviazione significativo rispetto ad altri tipi di indice.

Indici con caratteri jolly

Un indice su campo singolo, indicizza tutti i percorsi sotto field, esclusi gli altri campi che si trovano nello stesso livello. Ad esempio, nel seguente documento di esempio

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

La 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".

Limiti

  • Gli indici con caratteri jolly non possono supportare gli indici univoci.
  • Gli indici con caratteri jolly non supportano il pushdown 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 termine con caratteri jolly e one o più termini di indice. { "pets.$**": 1, “familyName”: 1 }

Indici geospaziali

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

Il vCore di Azure Cosmos DB for MongoDB offre due tipi di indici geospaziali:

  • Indici 2dsphere, che supportano le query che interpretano la geometria su una sfera.
  • Indici 2d, che supportano le query che interpretano la geometria su un piano.

Indici 2d

Gli indici 2d sono supportati solo con lo stile di abbinamento delle coppie di coordinate legacy per l'archiviazione di dati geospaziali.

Utilizzare il metodo createIndex con l'opzione 2d per creare un indice geospaziale nel campo location.

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

Limiti

  • Solo il campo di posizione one può far parte dell'indice 2d e solo altri campi one non geospaziali possono far parte dell'indice compound 2d db.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 le coppie di coordinate legacy. Gli indici 2dSphere funzionano con lo stile GeoJSON di archiviazione dei dati, se vengono rilevati punti legacy, verranno convertiti in punti GeoJSON.

Utilizzare il metodo createIndex con l'opzione 2dsphere per creare un indice geospaziale nel campo location.

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

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

Limiti

  • Un indice composto che usa un indice regolare e un indice geospaziale non è supportato. La creazione di uno degli indici geospaziali comporta degli 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 dei buchi non funzionano. L'inserimento di un poligono con un buco non è impedito, anche se la query $geoWithin non riuscirà in questi scenari:

    1. Se la query stessa contiene un poligono con dei buchi

      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 che contiene un poligono con i buchi.

      [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. Il campo key è obbligatorio quando si utilizza geoNear.

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

Passaggi successivi