Docs Menu
Docs Home
/ /

Índices parciales

Los índices parciales solo indexan los documentos de una colección que cumplen con una expresión de filtro especificada. Al indexar un subconjunto de los documentos en una colección, los índices parciales requieren menos almacenamiento y reducen los costos de rendimiento para la creación y el mantenimiento de índices.

Para crear una partial índice, utilice el db.collection.createIndex() Método con la partialFilterExpression opción. La partialFilterExpression opción acepta un documento que especifica la condición de filtro mediante:

Por ejemplo, la siguiente operación crea un índice compuesto que indexa solo los documentos donde el campo genre es Drama:

db.movies.createIndex(
{ title: 1 },
{ partialFilterExpression: { genres: "Drama" } }
)

Puedes especificar una opción partialFilterExpression para todos los tipos de índicesde MongoDB. Al especificar un partialFilterExpression para un índice TTL en una colección de series de tiempo, solo puedes filtrar en la colección metaField.

Tip

Para aprender a gestionar índices en MongoDB Compass, consulte Gestionar índices.

MongoDB no usará el índice parcial para una operación de query o clasificación si el uso del índice da como resultado un conjunto de resultados incompleto.

Para usar el índice parcial, una query debe contener la expresión de filtro (o una expresión de filtro modificada que especifique un subconjunto de la expresión de filtro) como parte de su condición de query.

Por ejemplo, dado el siguiente índice:

db.users.createIndex(
{ name: 1 },
{ partialFilterExpression: { password: { $exists: true } } }
)

La siguiente consulta puede utilizar el índice ya que el predicado de la consulta incluye la condición password: { $exists: true } que coincide con los documentos que coinciden con la expresión de filtro de índice password: { $exists: true }:

db.users.find( { name: "Ned Stark", password: { $exists: true } } )

Sin embargo, la siguiente consulta no puede usar el índice parcial en el campo name porque al usar el índice se obtiene un conjunto de resultados incompleto. En concreto, el predicado de la consulta incluye la condición password: { $exists: false }, mientras que el índice tiene el filtro password: { $exists: true }. Es decir, la consulta { name: "Ned Stark", password: { $exists: false } } coincide con más documentos (usuarios sin contraseña) de los que abarca el índice.

db.users.find( { name: "Ned Stark", password: { $exists: false } } )

De manera similar, la siguiente query no puede usar el índice parcial porque el predicado de la query no incluye la expresión del filtro y usar el índice devolvería un conjunto de resultados incompleto.

db.users.find( { name: "Ned Stark" } )

Usa índices parciales en lugar de índices dispersos si deseas un control más preciso sobre qué documentos indexar:

  • Los índices dispersos incluyen o excluyen documentos únicamente basándose en la existencia del campo indexado (o de múltiples campos, en el caso de índices compuestos dispersos).

  • Los índices parciales incluyen o no documentos según la expresión del filtro. La expresión puede incluir campos además de las claves de índice y puede especificar condiciones distintas a la existencia de un campo.

Por ejemplo, un índice parcial puede implementar el mismo comportamiento que un índice disperso. Este índice parcial admite las mismas queries que un índice disperso en el campo name:

db.users.createIndex(
{ name: 1 },
{ partialFilterExpression: { name: { $exists: true } } }
)

Sin embargo, un índice parcial también puede filtrar en campos distintos de la clave del índice. Por ejemplo, un índice parcial en el campo name puede verificar la existencia del campo email:

db.users.createIndex(
{ name: 1 },
{ partialFilterExpression: { email: { $exists: true } } }
)

Para que el optimizador de la query elija este índice parcial, el predicado de la consulta debe incluir una condición en el campo name así como una coincidencia no nula en el campo email.

Por ejemplo, la siguiente query puede utilizar el índice porque incluye tanto una condición en el campo name como una coincidencia no nula en el campo email

db.users.find( { name: "Ned Stark", email: { $regex: /gameofthron\.es$/ } } )

Sin embargo, la siguiente query no puede utilizar el índice porque incluye una coincidencia nula en el campo email, lo que no está permitido por la expresión de filtro { email: { $exists: true } }:

db.users.find( { name: "Ned Stark", email: { $exists: false } } )

Los índices parciales también pueden ser índices TTL. Los índices TTL parciales coinciden con la expresión de filtro especificada y solo expiran esos documentos. Para obtener más detalles, consulta Expirar documentos con condiciones de filtro.

  • No puedes especificar tanto la opción partialFilterExpression como la opción sparse.

  • _id los índices no pueden ser índices parciales.

  • Los índices de clave de partición no pueden ser índices parciales.

  • Si estás utilizando cifrado a nivel de campo del lado del cliente o Queryable Encryption, un partialFilterExpression no puede hacer referencia a un campo cifrado.

Los ejemplos de esta página utilizan datos de Conjunto de datos de muestra sample_mflix. Para obtener más información sobre cómo cargar este conjunto de datos en su implementación de MongoDB autogestionada, consulte Cargar el conjunto de datos de muestra. Si realizó alguna modificación en las bases de datos de muestra, es posible que deba eliminarlas y volver a crearlas para ejecutar los ejemplos de esta página.

El siguiente ejemplo agrega un índice parcial en los campos title y genres. La operación solo indexa documentos donde el campo rating es PG:

db.movies.createIndex(
{ title: 1, genres: 1 },
{ partialFilterExpression: { rated: "PG" } }
)

La siguiente consulta en la colección movies utiliza el índice parcial para devolver los escritores de todas las películas tituladas "Los tres mosqueteros":

db.movies.find( { title: "The Three Musketeers", genres: ["Action", "Adventure", "Comedy"], rated: "PG" }, { writers: 1 } )

Sin embargo, la siguiente consulta no puede utilizar el índice parcial porque el predicado de la consulta no incluye el filtro rating:

db.movies.find( { genres: "Drama" }, { title: 1 } ).limit(5)

Los índices parciales solo indexan los documentos de una colección que cumplen con una expresión de filtro especificada. Si especificas tanto el partialFilterExpression como una restricción única, la restricción única solo se aplica a los documentos que cumplen con la expresión de filtro. Un índice parcial con una restricción de unicidad no impide la inserción de documentos que no cumplan dicha restricción si estos no cumplen con los criterios de filtrado.

La siguiente operación en la users colección crea un índice que especifica una restricción única en el email campo y una expresión de filtro password: { $exists: true } parcial.

db.users.createIndex(
{ name: 1 },
{ name: "name_partial_unique_idx", unique: true, partialFilterExpression: { password: { $exists: true } } }
)

El índice impide la inserción de los documentos que tienen tanto una dirección de correo electrónico que ya existe en la colección como un campo password ya existente.

Sin embargo, se permiten los siguientes documentos con nombres de usuario duplicados, ya que la restricción de unicidad solo se aplica a los documentos con age mayor o igual a 21.

db.users.insertMany( [
{ username: "david", age: 20 },
{ username: "amanda" },
{ username: "rajiv", age: null }
] )

Volver

Oculto

En esta página