Compartir a través de


Administración de la indexación en Azure DocumentDB

Los índices son estructuras que mejoran la velocidad de recuperación de datos al proporcionar acceso rápido a los campos de una colección. Funcionan creando un conjunto ordenado de punteros a datos, a menudo basados en campos clave. Azure DocumentDB utiliza índices en varios contextos, como la optimización de consultas, las restricciones únicas y la compartimentación.

Importante

El campo "_id" es el único campo indexado de forma predeterminada y el tamaño máximo del campo puede ser 2 KB. Se recomienda agregar índices adicionales basados en filtros de consulta y predicados para optimizar el rendimiento.

Tipos de índice

Para simplificar, consideremos un ejemplo de una aplicación de blog con la siguiente configuración:

  • Nombre de base de datos: cosmicworks
  • Nombre de la colección: products

En esta aplicación de ejemplo se almacenan artículos como documentos con la estructura siguiente. Todos los ejemplos citados usan la estructura de esta colección.

{
  "_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
}

Índices de campo único

Los índices de campo único almacenan información de un único campo de una colección. No importa el criterio de ordenación del índice de campo único. _id el campo permanece indexado de forma predeterminada.

Azure DocumentDB admite la creación de índices a continuación

  • Campos de documento de nivel superior.
  • Documento incrustado.
  • Campos dentro del documento incrustado.

El comando siguiente crea un índice de campo único en el campo author y el siguiente comando lo crea en un campo firstNameincrustado .

use cosmicworks

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

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

Una consulta puede usar varios índices de campo único cuando estén disponibles.

Nota:

Azure DocumentDB permite crear un máximo de 64 índices en una colección. En función del nivel, podemos planear la extensión hasta 300 índices a petición.

Índices compuestos

Los índices compuestos mejoran el rendimiento de la base de datos al permitir consultas y ordenación eficaces en función de varios campos dentro de los documentos. Esta optimización reduce la necesidad de examinar colecciones completas, lo que acelera la recuperación de datos y la organización.

El comando siguiente crea un índice compuesto en los campos author y launchDate en orden opuesto.

use cosmicworks

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

Order de los campos afectan a la selectividad o al uso del índice. La find consulta no usaría el índice creado.

use cosmicworks

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

Limitaciones

  • Máximo de 32 campos\rutas de acceso dentro de un índice compuesto.

Índices parciales

Índices que tienen un filtro de consulta asociado que describe cuándo generar un término en el índice.

use cosmicworks

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

Limitaciones

  • Los índices parciales no admiten ORDER BY o UNIQUE a menos que el filtro cumpla los criterios.

Índices de texto

Los índices de texto son estructuras de datos especiales que optimizan las consultas basadas en texto, lo que las hace más rápidas y eficaces.

Use el createIndex método con la text opción para crear un índice de texto en el title campo.

use cosmicworks;

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

Nota:

Aunque solo puede definir un índice de texto por colección, Azure DocumentDB le permite crear índices de texto en combinación de varios campos para permitirle realizar búsquedas de texto en distintos campos de los documentos.

Configuración de opciones de índice de texto

Los índices de texto de Azure DocumentDB incluyen varias opciones para personalizar su comportamiento. Por ejemplo, puede especificar el idioma para el análisis de texto, establecer ponderaciones para priorizar determinados campos y configurar búsquedas que no distinguen mayúsculas de minúsculas. Este es un ejemplo de creación de un índice de texto con opciones:

  • Cree un índice para admitir la búsqueda en los title campos y content con compatibilidad con el idioma inglés. Además, asigne pesos más altos al title campo para priorizarlo en los resultados de búsqueda.

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

Nota:

Cuando un cliente realiza una consulta de búsqueda de texto con el término "DocumentDB", la puntuación de cada documento de la colección se calculará en función de la presencia y frecuencia del término en los campos "title" y "content", con mayor importancia dada al campo "title" debido a su mayor peso.

Realizar una búsqueda de texto mediante un índice de texto

Una vez creado el índice de texto, puede realizar búsquedas de texto mediante el operador "text" en las consultas. El operador de texto toma una cadena de búsqueda y la coincide con el índice de texto para buscar documentos relevantes.

  • Realice una búsqueda de texto para la frase DocumentDB.

    use cosmicworks
    
    db.products.find(
      { $text: { $search: "DocumentDB" } }
    )
    
  • Opcionalmente, use el operador de proyección $meta junto con el campo textScore en una consulta para ver el peso

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

Limitaciones

  • Solo se puede definir un índice de texto en una colección.
  • Las operaciones de ordenación no pueden usar el orden del índice de texto en MongoDB.
  • Hint() no se admite en combinación con una consulta mediante la expresión $text.
  • Los índices de texto pueden ser relativamente grandes y consumir espacio de almacenamiento significativo en comparación con otros tipos de índice.

Índices comodín

Índice en un solo campo, indexa todas las rutas de acceso debajo de field , excepto otros campos que están en el mismo nivel. Por ejemplo, para el siguiente documento de ejemplo

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

Crear un índice en { "pets.$**": 1 }, crea un índice sobre las propiedades de detalles y subdocumentos, pero no crea un índice en "familyName".

Limitaciones

  • Los índices comodín no pueden admitir índices únicos.
  • Los índices comodín no admiten inserciones de ORDER BY a menos que el filtro incluya solo rutas de acceso presentes en el carácter comodín (ya que no indexan elementos sin definir)
  • Un índice compuesto de comodín solo puede tener one un término comodín y one o más términos de índice. { "pets.$**": 1, “familyName”: 1 }

Índices geoespaciales

Los índices geoespaciales admiten consultas en los datos almacenados como objetos GeoJSON o pares de coordenadas heredados. Puede usar índices geoespaciales para mejorar el rendimiento de las consultas en datos geoespaciales o para ejecutar determinadas consultas geoespaciales.

Azure DocumentDB proporciona dos tipos de índices geoespaciales:

  • Índices 2dsphere, que admiten consultas que interpretan la geometría en una esfera.
  • Índices 2d, que admiten consultas que interpretan la geometría en una superficie plana.

Índices 2D

Los índices 2d solo se admiten con el estilo heredado del par de coordenadas de almacenamiento de datos geoespaciales.

Use el createIndex método con la 2d opción para crear un índice geoespacial en el location campo.

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

Limitaciones

  • Solo one el campo de ubicación puede formar parte del 2d índice y solo otro one campo no geoespacial puede formar parte del compound 2d índice. db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1 })

Índices 2dsphere

2dsphere los índices admiten consultas geoespaciales en una esfera similar a la tierra. Puede admitir objetos GeoJSON o pares de coordenadas heredados. 2dSphere los índices funcionan con el estilo GeoJSON de almacenar datos, si se encuentran puntos heredados, se convertirá en punto GeoJSON.

Use el createIndex método con la 2dsphere opción para crear un índice geoespacial en el location campo.

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

2dsphere los índices permiten crear índices en varios campos de datos geoespaciales y varios no geoespaciales. db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1, ... "more non-geospatial-field": 1 / -1 })

Limitaciones

  • No se admite un índice compuesto mediante un índice normal y un índice geoespacial. La creación de cualquiera de los índices geoespaciales provocaría errores.

    // 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})
    
  • Los polígonos con agujeros no funcionan. La inserción de un polígono con agujero no está restringida, aunque la consulta $geoWithin falla en escenarios:

    1. Si la propia consulta tiene polígono con agujeros

      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. Si hay algún documento sin filtrar que tenga polígono con agujeros.

      [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. El campo key es obligatorio mientras se usa geoNear.

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

Pasos siguientes