Un índice único garantiza que los campos indexados no almacenen valores duplicados; es decir, aplica la unicidad para los campos indexados. De forma predeterminada, MongoDB crea un índice único en el _id campo durante la creación de una colección.
Nota
Nuevo formato interno
A partir de MongoDB 4.2, para la featureCompatibilityVersion (fCV) de 4.2 (o superior), MongoDB utiliza un nuevo formato interno para índices únicos que es incompatible con versiones anteriores de MongoDB. El nuevo formato se aplica tanto a los índices únicos existentes como a los índices únicos recién creados/reconstruidos.
Se puede crear y gestionar índices únicos en la Interfaz de Usuario para implementaciones alojadas en MongoDB Atlas.
Crear un índice único
Para crear un índice único, utilice el db.collection.createIndex() método con la opción unique configurada a true.
db.collection.createIndex( <key and index type specification>, { unique: true } )
Índice único en un solo campo
Por ejemplo, para crear un índice único en el campo user_id de la colección members, utiliza la siguiente operación en mongosh:
db.members.createIndex( { "user_id": 1 }, { unique: true } )
Índice compuesto único
También puede aplicar una restricción única a los índices compuestos. Si utiliza la restricción única en un índice compuesto, MongoDB aplicará la unicidad a la combinación de los valores de la clave del índice.
Por ejemplo, para crear un índice único en groupNumber loslastname campos, y firstname de la members colección, utilice la siguiente operación mongosh en:
db.members.createIndex( { groupNumber: 1, lastname: 1, firstname: 1 }, { unique: true } )
El índice creado aplica la unicidad para la combinación de los valores de groupNumber, lastname, y firstname.
Para otro ejemplo, considere una colección con el siguiente documento:
{ _id: 1, a: [ { loc: "A", qty: 5 }, { qty: 10 } ] }
Crea un índice compuesto único multikey en a.loc y a.qty:
db.collection.createIndex( { "a.loc": 1, "a.qty": 1 }, { unique: true } )
El índice único permite la inserción de los siguientes documentos en la colección, ya que el índice aplica la unicidad de la combinación de valores de a.loc y a.qty:
db.collection.insertMany( [ { _id: 2, a: [ { loc: "A" }, { qty: 5 } ] }, { _id: 3, a: [ { loc: "A", qty: 10 } ] } ] )
Comportamiento
Restricciones
MongoDB no puede crear un índice único en los campos de índice especificados si la colección ya contiene datos que violarían la restricción única del índice.
No puede especificar una restricción única en un índice hash.
Creación de un índice único en sets de réplicas y clústeres particionados
Para sets de réplicas y clústeres, el uso de un procedimiento escalonado para crear un índice único requiere que se detengan todos los guardados en la colección durante el procedimiento. Si no puedes detener todos los guardados en la colección durante el procedimiento, no uses el procedimiento de desplazamiento. En su lugar, compilar un índice único en la colección por:
emitiendo en el primario para un conjunto de réplicas,
db.collection.createIndex()oemitir
db.collection.createIndex()en elmongospara un clúster particionado.
Restricción única entre documentos separados
La restricción única se aplica a documentos separados en la colección. Es decir, el índice único impide que documentos separados tengan el mismo valor para la clave indexada.
Debido a que la restricción se aplica a documentos separados, para un índice multiclave único, un documento puede tener elementos de arreglos que resulten en valores de clave de índice repetidos, siempre que los valores de clave de índice para ese documento no dupliquen los de otro documento. En este caso, la entrada de índice repetida se inserta en el índice una sola vez.
Por ejemplo, considera una colección con los siguientes documentos:
{ _id: 1, a: [ { loc: "A", qty: 5 }, { qty: 10 } ] } { _id: 2, a: [ { loc: "A" }, { qty: 5 } ] } { _id: 3, a: [ { loc: "A", qty: 10 } ] }
Crear un índice multiclave compuesto único en a.loc y a.qty:
db.collection.createIndex( { "a.loc": 1, "a.qty": 1 }, { unique: true } )
El índice único permite la inserción del siguiente documento en la colección si ningún otro documento en la colección tiene un valor de clave de índice de { "a.loc": "B", "a.qty": null }.
db.collection.insertOne( { _id: 4, a: [ { loc: "B" }, { loc: "B" } ] } )
Campo de documento ausente en un índice único de campo único
Si un documento tiene un valor null o falta un valor para el campo indexado en un índice de campo único, el índice almacena un valor null para ese documento. Debido a la restricción de unicidad, un índice único de un solo campo solo puede contener un documento que tenga un valor null en la entrada de índice. Si hay más de un documento con un valor de null en la entrada de índice, la creación de índices falla y muestra un error de clave duplicada.
Por ejemplo, una colección tiene un índice único de un solo campo en x:
db.collection.createIndex( { "x": 1 }, { unique: true } )
El índice único permite la inserción de un documento sin el campo x si la colección no contiene ya un documento que carezca del campo x:
db.collection.insertOne( { y: 1 } )
Sin embargo, no se puede insertar un documento sin el campo x si la colección ya contiene un documento que carece del campo x:
db.collection.insertOne( { z: 1 } )
La operación no puede insertar el documento debido a la violación de la restricción única en el valor del campo x:
WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error index: test.collection.$a.b_1 dup key: { : null }" } })
Campos de documento faltantes en un índice compuesto único
Si un documento tiene un valor null o faltante para uno o más campos indexados en un índice compuesto único, el índice almacena un valor nulo para cada campo null o faltante en la entrada de índice del documento. Debido a la restricción única, un índice compuesto único solo permite un documento que tenga un valor null para todos los campos indexados en una entrada de índice. Si hay más de una entrada de índice con un valor null para todos los campos indexados, la creación de índices falla y muestra un error de clave duplicada. MongoDB permite múltiples documentos con campos faltantes en índices compuestos únicos siempre que cada entrada de índice sea única.
Por ejemplo, una colección students tiene un índice compuesto único en los campos name, age y grade:
db.students.createIndex( { "name": 1, "age": -1, "grade": 1 }, { unique: true } )
Si la colección no contiene ya documentos idénticos, el índice compuesto único permite la inserción de los siguientes documentos a los que les falta el campo grade.
db.students.insertMany( [ { "name": "Meredith", "age": 12 }, { "name": "Olivia", "age": 11 }, { "name": "Benjamin" } ] )
Sin embargo, no se puede insertar un documento que tenga la misma clave de índice (valor para name, age y grade) que otro documento de la colección.
db.students.insertOne( { name: "Meredith", age: 12 } )
La operación falla al insertar el documento debido a la violación de la restricción única en los valores de los campos name, age y grade:
WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error collection: test.students index: name_1_age_-1_grade_1 dup key: { name: "Meredith", age: 12, grade: null } } } )
Tampoco se puede insertar un documento que sea único, pero comparta una clave de índice con una entrada de índice ya existente.
db.students.insertOne( { name: "Olivia", "age": 11, "favorite color": "red"} )
La operación falla al insertar el documento debido a la violación de la restricción única en los valores de los campos name, age y grade:
WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error collection: test.students index: name_1_age_-1_grade_1 dup key: { name: "Olivia", age: 11, grade: null } } } )
Índices parciales únicos
Los índices parciales solo indexan los documentos en una colección que cumplan con una expresión de filtro especificada. Si se especifica 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 única no impide la inserción de documentos que no cumplan con la restricción única si los documentos no cumplen con los criterios del filtro. Para un ejemplo, ver Índice parcial con restricción única.
Clústeres particionados e índices únicos
No puedes especificar una restricción única en un índice encriptado.
Para una colección particionada clasificada por rango, solo los siguientes índices pueden ser únicos:
el índice de la clave del fragmento
Un índice compuesto donde la clave de partición es un prefijo
El índice
_idpor defecto; sin embargo, el índice_idsolo aplica la restricción de unicidad por fragmento si el campo_idno es la clave de fragmentación.
Importante
Los clústeres particionados no aplican la restricción de unicidad en los campos _id en todo el clúster cuando el campo _id no es la clave de partición.
Si el campo _id no es la clave de partición, la restricción de unicidad solo se aplica al shard que almacena el documento. Esto significa que dos o más documentos pueden tener el mismo valor de _id, siempre que se encuentren en particiones diferentes.
Por ejemplo, una colección particionada con la clave de partición {x:
1} que se extiende por dos particiones A y B. Dado que la clave _id no es la clave de partición, la colección podría tener un documento con el valor _id 1 en la partición A y otro documento con el valor _id 1 en el partición B.
En los casos en que el campo _id no sea la clave de partición, MongoDB espera que las aplicaciones apliquen la unicidad de los valores _id en todas las particiones.
Las restricciones de índices únicos implican que:
Para una colección particionada, no puede fragmentarse la colección si tiene varios índices únicos, a menos que la clave de partición sea el prefijo de todos los índices únicos.
Para una colección ya particionada, no puedes crear índices únicos en otros campos a menos que la clave de partición se incluya como prefijo.
Un índice único almacena un valor nulo para un documento que carece del campo indexado; es decir, un campo de índice ausente se trata como otra instancia de un valor de clave de índice
null. Para obtener más información, consulta Campo de documento faltante en un índice único de un solo campo.
Para mantener la singularidad en un campo que no es la clave de partición, se debe consultar Restricciones de singularidad en campos arbitrarios.
Índices únicos escasos y no escasos
A partir de MongoDB 5.0, pueden existir índices únicos dispersos e índices únicos no dispersos con el mismo patrón de clave en una sola colección.
Creación de índices únicos y dispersos
Este ejemplo crea múltiples índices con el mismo patrón de clave y diferentes opciones de sparse:
db.scoreHistory.createIndex( { score : 1 }, { name: "unique_index", unique: true } ) db.scoreHistory.createIndex( { score : 1 }, { name: "unique_sparse_index", unique: true, sparse: true } )
Creación de índices básicos y dispersos
También se pueden crear índices básicos con el mismo patrón de claves con y sin la opción de dispersión:
db.scoreHistory.createIndex( { score : 1 }, { name: "sparse_index", sparse: true } ) db.scoreHistory.createIndex( { score : 1 }, { name: "basic_index" } )
Índices básicos y únicos con patrones de claves duplicadas
A partir de MongoDB 5.0, los índices básicos y únicos pueden existir con el mismo patrón de clave.
Esta duplicación en los patrones de clave permite agregar un índice único a los campos que ya están indexados.
En este ejemplo:
Crear un índice básico con el patrón de clave { score : 1 } e insertar tres documentos.
db.scoreHistory.createIndex( { score : 1 }, { name: "basic_index" } ) db.scoreHistory.insert( { score : 1 } ) db.scoreHistory.insert( { score : 2 } ) db.scoreHistory.insert( { score : 3 } )
Cree un índice único con el mismo patrón de clave { score : 1 }.
db.scoreHistory.createIndex( { score : 1 }, { name: "unique_index", unique: true } )
Prueba insertar un documento score duplicado que falle debido al índice único.
db.scoreHistory.insert( { score : 3 } )