Compartir vía


Administración de la indexación en Azure Cosmos DB for MongoDB

Azure Cosmos DB for MongoDB le permite usar la indexación para acelerar el rendimiento de las consultas. En este artículo, se muestra cómo administrar y optimizar índices para una recuperación de datos más rápida y una mejor eficacia.

Indexación del servidor de MongoDB versión 3.6 y superiores

Azure Cosmos DB para el servidor de MongoDB versión 3.6 y superiores indexa automáticamente el campo _id y la clave de partición (solo en colecciones particionadas). La API aplica la unicidad del campo _id por clave de partición.

La API para MongoDB funciona de forma diferente de Azure Cosmos DB for NoSQL, que indexa todos los campos de forma predeterminada.

Edición de la directiva de indexación

Edite la directiva de indexación en el Explorador de datos en Azure Portal. Agregue índices de campo único y comodín desde el editor de directivas de indexación en el Explorador de datos:

Captura de pantalla del editor de directivas de indexación en Azure Cosmos DB for MongoDB.

Nota:

No se pueden crear índices compuestos mediante el editor de directivas de indexación en Data Explorer.

Tipos de índice

Campo único

Cree un índice en cualquier campo único. No importa el criterio de ordenación del índice de campo único. Use el comando siguiente para crear un índice en el campo name:

db.coll.createIndex({name:1})

Cree el mismo índice de campo único en name en Azure Portal:

Captura de pantalla de cómo agregar un índice de nombre en el editor de directivas de indexación.

Una consulta usa varios índices de campo únicos cuando están disponibles. Cree hasta 500 índices de campo único por colección.

Índices compuestos (servidor de MongoDB versión 3.6 y superiores)

En la API para MongoDB, use índices compuestos con consultas que ordenen varios campos a la vez. En el caso de las consultas con varios filtros que no es necesario ordenar, cree varios índices de campo único en lugar de un índice compuesto para ahorrar en costes de indexación.

Un índice compuesto o los índices de campo único para cada campo del índice compuesto da como resultado el mismo rendimiento para el filtrado de las consultas.

Los índices compuestos en campos anidados no se admiten de forma predeterminada debido a limitaciones con las matrices. Si un campo anidado no tiene una matriz, el índice funciona según lo previsto. Si un campo anidado tiene una matriz en cualquier parte de la ruta de acceso, ese valor se omite en el índice.

Por ejemplo, un índice compuesto que contiene people.dylan.age funciona en este caso porque no hay ninguna matriz en la ruta de acceso:

{
  "people": {
    "dylan": {
      "name": "Dylan",
      "age": "25"
    },
    "reed": {
      "name": "Reed",
      "age": "30"
    }
  }
}

El mismo índice compuesto no funciona en este caso porque hay una matriz en la ruta de acceso:

{
  "people": [
    {
      "name": "Dylan",
      "age": "25"
    },
    {
      "name": "Reed",
      "age": "30"
    }
  ]
}

Habilite esta característica para la cuenta de base de datos habilitando la funcionalidad "EnableUniqueCompoundNestedDocs".

Nota:

No se pueden crear índices compuestos en matrices.

El comando siguiente crea un índice compuesto en los campos name y age:

db.coll.createIndex({name:1,age:1})

Puede utilizar índices compuestos para ordenar de forma eficaz en varios campos a la vez, tal como se muestra en el ejemplo siguiente:

db.coll.find().sort({name:1,age:1})

También se puede usar el índice compuesto anterior para una ordenación eficaz en una consulta con el criterio de ordenación opuesto en todos los campos. Este es un ejemplo:

db.coll.find().sort({name:-1,age:-1})

Sin embargo, la secuencia de las rutas de acceso en el índice compuesto debe coincidir exactamente con la consulta. Este es un ejemplo de una consulta que requeriría un índice compuesto adicional:

db.coll.find().sort({age:1,name:1})

Índice de varias claves

Azure Cosmos DB crea índices multiclave para indexar contenido en matrices. Si indexa un campo con un valor de matriz, Azure Cosmos DB indexa automáticamente cada elemento de la matriz.

Índices geoespaciales

Muchos operadores geoespaciales se benefician de los índices geoespaciales. Azure Cosmos DB for MongoDB admite índices 2dsphere. La API aún no admite los índices2d.

A continuación, se muestra un ejemplo para crear un índice geoespacial en el campo location:

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

Índices de texto

Azure Cosmos DB for MongoDB no admite índices de texto. Para las consultas de búsqueda de texto en cadenas, use la integración de Búsqueda de Azure AI con Azure Cosmos DB.

Índices con caracteres comodín

Use índices comodín para admitir consultas en campos desconocidos. Imagine una colección que tiene datos sobre familias.

Esta es parte de un documento de ejemplo de esa colección:

"children": [
  {
    "firstName": "Henriette Thaulow",
    "grade": "5"
  }
]

Este es otro ejemplo con un conjunto diferente de propiedades en children:

"children": [
  {
    "familyName": "Merriam",
    "givenName": "Jesse",
    "pets": [
      { "givenName": "Goofy" },
      { "givenName": "Shadow" }
    ]
  },
  {
    "familyName": "Merriam",
    "givenName": "John",
  }
]

Los documentos de esta colección pueden tener muchas propiedades diferentes. Para indexar todos los datos de la matriz children, cree índices independientes para cada propiedad o cree un índice comodín para toda la matriz children.

Creación de un índice de caracteres comodín

Use el comando siguiente para crear un índice comodín en las propiedades de children:

db.coll.createIndex({"children.$**" : 1})
  • A diferencia de MongoDB, los índices de caracteres comodín pueden admitir varios campos en predicados de consulta. No hay ninguna diferencia en el rendimiento de las consultas si usa un único índice comodín en lugar de crear un índice independiente para cada propiedad.

Cree los siguientes tipos de índice con la sintaxis de caracteres comodín:

  • Campo único
  • Geoespaciales

Indexación de todas las propiedades

Cree un índice comodín en todos los campos con el comando siguiente:

db.coll.createIndex( { "$**" : 1 } )

Cree índices comodín mediante el Explorador de datos en Azure Portal:

Agregar un índice de caracteres comodín en el editor de directivas de indexación

Nota:

Si acaba de iniciar el desarrollo, comience con un índice comodín en todos los campos. Este enfoque simplifica el desarrollo y facilita la optimización de las consultas.

Los documentos con muchos campos pueden tener un cargo elevado de unidad de solicitud (RU) por las escrituras y las actualizaciones. Si tiene una carga de trabajo con mucha escritura, use rutas de acceso con indexación individual en lugar de caracteres comodín.

Limitaciones

Los índices de caracteres comodín no admiten ninguno de los siguientes tipos o propiedades de índice:

  • Compuesto

  • TTL

  • Único

  • A diferencia de MongoDB, en Azure Cosmos DB for MongoDB, no puede usar índices comodín para:

  • Crear un índice de caracteres comodín que incluya varios campos específicos

    db.coll.createIndex(
      { "$**" : 1 },
      { "wildcardProjection " :
        {
          "children.givenName" : 1,
          "children.grade" : 1
        }
      }
    )
    
  • Crear un índice de caracteres comodín que excluya varios campos específicos

    db.coll.createIndex(
      { "$**" : 1 },
      { "wildcardProjection" :
        {
          "children.givenName" : 0,
          "children.grade" : 0
        }
      }
    )
    

Como alternativa, cree varios índices comodín.

Propiedades de índice

Las siguientes operaciones son comunes para las cuentas que usan la versión 4.0 del protocolo de conexión y versiones anteriores. Obtenga más información sobre los índices admitidos y las propiedades de índice.

Índices únicos

Los índices únicos ayudan a garantizar que dos o más documentos no tengan el mismo valor para los campos indexados.

Ejecute el comando siguiente para crear un índice único en el campo student_id:

db.coll.createIndex( { "student_id" : 1 }, {unique:true} )

{
  "_t" : "CreateIndexesResponse",
  "ok" : 1,
  "createdCollectionAutomatically" : false,
  "numIndexesBefore" : 1,
  "numIndexesAfter" : 4
}

En el caso de las colecciones particionadas, proporcione la clave de partición para crear un índice único. Todos los índices únicos de una colección particionada son índices compuestos y uno de los campos es la clave de partición. La clave de partición debe ser el primer campo de la definición del índice.

Ejecute los siguientes comandos para crear una colección particionada denominada coll (con university como clave de partición) y un índice único en los campos student_id y university:

db.runCommand({shardCollection: db.coll._fullName, key: { university: "hashed"}});
{
  "_t" : "ShardCollectionResponse",
  "ok" : 1,
  "collectionsharded" : "test.coll"
}
db.coll.createIndex( { "university" : 1, "student_id" : 1 }, {unique:true});
{
  "_t" : "CreateIndexesResponse",
  "ok" : 1,
  "createdCollectionAutomatically" : false,
  "numIndexesBefore" : 3,
  "numIndexesAfter" : 4
}

Si omite la cláusula "university":1 en el ejemplo anterior, verá el siguiente mensaje de error:

cannot create unique index over {student_id : 1.0} with shard key pattern { university : 1.0 }

Limitaciones

Cree índices únicos mientras la colección está vacía.

Las cuentas de Azure Cosmos DB para MongoDB con copia de seguridad continua no admiten la creación de un índice único para una colección existente. Para esta cuenta, se deben crear índices únicos junto con la creación de la colección, que solo se puede hacer mediante los comandos de extensión de creación de colecciones.

db.runCommand({customAction:"CreateCollection", collection:"coll", shardKey:"student_id", indexes:[
{key: { "student_id" : 1}, name:"student_id_1", unique: true}
]});

Los índices únicos en campos anidados no se admiten de forma predeterminada debido a limitaciones con las matrices. Si el campo anidado no tiene una matriz, el índice funciona según lo previsto. Si el campo anidado tiene una matriz en cualquier parte de la ruta de acceso, ese valor se omite en el índice único y la unicidad no se conserva para ese valor.

Por ejemplo, un índice único en people.tom.age funciona en este caso porque no hay ninguna matriz en la ruta de acceso:

{
  "people": {
    "tom": {
      "age": "25"
    },
    "mark": {
      "age": "30"
    }
  }
}

Pero no funciona en este caso porque hay una matriz en la ruta de acceso:

{
  "people": {
    "tom": [
      {
        "age": "25"
      }
    ],
    "mark": [
      {
        "age": "30"
      }
    ]
  }
}

Esta característica se puede habilitar para la cuenta de base de datos habilitando la funcionalidad "EnableUniqueCompoundNestedDocs".

Índices TTL

Para permitir que los documentos expiren en una colección, cree un índice de período de vida (TTL). Un índice TTL es un índice del campo _ts con un valor expireAfterSeconds.

Ejemplo:

db.coll.createIndex({"_ts":1}, {expireAfterSeconds: 10})

El comando anterior elimina los documentos de la colección db.coll que se modificaron hace más de 10 segundos.

Nota:

El campo _ts es específico de Azure Cosmos DB y no es accesible desde clientes de MongoDB. Es una propiedad (de sistema) reservada que contiene la marca de tiempo de la última modificación del documento.

Seguimiento del progreso del índice

La versión 3.6+ de Azure Cosmos DB for MongoDB admite el comando currentOp() para realizar un seguimiento del progreso del índice en una instancia de base de datos. Este comando devuelve un documento con información sobre las operaciones en curso en una instancia de base de datos. Use el comando currentOp para realizar un seguimiento de todas las operaciones en curso en MongoDB nativo. En Azure Cosmos DB for MongoDB, este comando solo realiza un seguimiento de la operación de índice.

Estos son algunos ejemplos de cómo usar el comando currentOp para realizar un seguimiento del progreso del índice:

  • Para obtener el progreso del índice de una colección:

    db.currentOp({"command.createIndexes": <collectionName>, "command.$db": <databaseName>})
    
  • Para obtener el progreso del índice de todas las colecciones de una base de datos:

    db.currentOp({"command.$db": <databaseName>})
    
  • Para obtener el progreso del índice de todas las bases de datos y colecciones de una cuenta de Azure Cosmos DB:

    db.currentOp({"command.createIndexes": { $exists : true } })
    

Ejemplos de salida del progreso del índice

Los detalles del progreso del índice muestran el porcentaje de progreso de la operación de índice actual. Estos son ejemplos del formato del documento de salida para diferentes fases del progreso del índice:

  • Una operación de índice en una colección "foo" y una base de datos "bar" que está completa al 60 % tiene el siguiente documento de salida. En el campo Inprog[0].progress.total se muestra el 100% como porcentaje de finalización objetivo.

    {
      "inprog": [
        {
          ...
          "command": {
            "createIndexes": foo
            "indexes": [],
            "$db": bar
          },
          "msg": "Index Build (background) Index Build (background): 60 %",
          "progress": {
            "done": 60,
            "total": 100
          },
          ...
        }
      ],
      "ok": 1
    }
    
  • Si una operación de índice acaba de iniciarse en una colección "foo" y una base de datos "bar", el documento de salida puede mostrar un 0 por ciento de progreso hasta que alcance un nivel medible.

    {
      "inprog": [
        {
          ...
          "command": {
            "createIndexes": foo
            "indexes": [],
            "$db": bar
          },
          "msg": "Index Build (background) Index Build (background): 0 %",
          "progress": {
            "done": 0,
            "total": 100
          },
          ...
        }
      ],
      "ok": 1
    }
    
  • Cuando finalice la operación de índice, el documento de salida muestra operaciones inprog vacías.

    {
      "inprog" : [],
      "ok" : 1
    }
    

Actualizaciones de índices en segundo plano

Las actualizaciones de índice siempre se ejecutan en segundo plano, independientemente del valor que establezca para la propiedad de índice en segundo plano. Dado que las actualizaciones de índice usan unidades de solicitud (RU) con una prioridad menor que otras acciones de base de datos, los cambios de índice no provocan tiempo de inactividad para escrituras, actualizaciones o eliminaciones.

Agregar un nuevo índice no afecta a la disponibilidad de lectura. Las consultas usan índices nuevos solo después de que finalice la transformación del índice. Durante la transformación, el motor de consultas sigue usando índices existentes, por lo que verá un rendimiento de lectura similar al que se tenía antes de iniciar el cambio de indexación. Al agregar nuevos índices no se corre el riesgo de obtener resultados de consulta incompletos o incoherentes.

Si quita índices y ejecuta inmediatamente consultas que filtran los índices eliminados, los resultados pueden ser incoherentes e incompletos hasta que finalice la transformación del índice. El motor de consultas no proporciona resultados coherentes ni completos para las consultas que filtran los índices recién quitados. La mayoría de los desarrolladores no quitan índices para consultarlos inmediatamente después, por lo que esta situación es poco probable.

Comando reIndex

El comando reIndex vuelve a crear todos los índices de una colección. En raras ocasiones, ejecutar el comando reIndex puede corregir el rendimiento de las consultas u otros problemas de índice de la colección. Si experimenta problemas de indexación, intente volver a crear los índices con el comando reIndex.

Ejecute el comando reIndex con la siguiente sintaxis:

db.runCommand({ reIndex: <collection> })

Use la sintaxis siguiente para comprobar si la ejecución del comando reIndex mejora el rendimiento de las consultas en la colección:

db.runCommand({"customAction":"GetCollection",collection:<collection>, showIndexes:true})

Resultados del ejemplo:

{
  "database": "myDB",
  "collection": "myCollection",
  "provisionedThroughput": 400,
  "indexes": [
    {
      "v": 1,
      "key": {
        "_id": 1
      },
      "name": "_id_",
      "ns": "myDB.myCollection",
      "requiresReIndex": true
    },
    {
      "v": 1,
      "key": {
        "b.$**": 1
      },
      "name": "b.$**_1",
      "ns": "myDB.myCollection",
      "requiresReIndex": true
    }
  ],
  "ok": 1
}

Si reIndex mejora el rendimiento de las consultas, requiresReIndex es true. Si reIndex no mejora el rendimiento de las consultas, se omite esta propiedad.

Migración de colecciones con índices

Solo puede crear índices únicos cuando la colección no tenga documentos. Las herramientas de migración populares de MongoDB intentan crear índices únicos después de importar los datos. Para solucionar este problema, cree manualmente las colecciones y los índices únicos correspondientes en lugar de permitir que la herramienta de migración lo intente. Se logra este comportamiento para mongorestore usando la marca --noIndexRestore en la línea de comandos.

Indexación de MongoDB versión 3.2

Las características de indexación y los valores predeterminados difieren para las cuentas de Azure Cosmos DB que usan la versión 3.2 del protocolo de conexión de MongoDB. Compruebe la versión de la cuenta en feature-support-36.md#protocol-support y actualice a la versión 3.6 en upgrade-version.md.

Si usa la versión 3.2, en esta sección se resaltan las diferencias clave de las versiones 3.6 y posteriores.

Eliminación de índices predeterminados (versión 3.2)

A diferencia de las versiones 3.6 y posteriores, Azure Cosmos DB for MongoDB versión 3.2 indexa cada propiedad de forma predeterminada. Use el siguiente comando para quitar estos índices predeterminados para una colección (coll):

db.coll.dropIndexes()
{ "_t" : "DropIndexesResponse", "ok" : 1, "nIndexesWas" : 3 }

Después de quitar los índices predeterminados, agregue más índices como lo hace en la versión 3.6 y posteriores.

Índices compuestos (versión 3.2)

Los índices compuestos hacen referencia a varios campos de un documento. Para crear un índice compuesto, actualice a la versión 3.6 o 4.0 en upgrade-version.md.

Índices de caracteres comodín (versión 3.2)

Para crear un índice comodín, actualice a la versión 4.0 o 3.6 en upgrade-version.md.

Pasos siguientes