MongoDB: Índice único en la propiedad del elemento de matriz

Tengo una estructura similar a esto:

class Cat { int id; List kittens; } class Kitten { int id; } 

Me gustaría evitar que los usuarios creen un gato con más de un gatito con la misma identificación. Intenté crear un índice de la siguiente manera:

 db.Cats.ensureIndex({'id': 1, 'kittens.id': 1}, {unique:true}) 

Pero cuando bash insertar un gato mal formateado, Mongo lo acepta.

¿Me estoy perdiendo de algo? ¿Puede esto siquiera estar terminado?

Por lo que yo sé, los índices únicos solo imponen la singularidad en diferentes documentos, por lo que arrojaría un error clave duplicado:

 db.cats.insert( { id: 123, kittens: [ { id: 456 } ] } ) db.cats.insert( { id: 123, kittens: [ { id: 456 } ] } ) 

Pero esto está permitido:

 db.cats.insert( { id: 123, kittens: [ { id: 456 }, { id: 456 } ] } ) 

No estoy seguro de si hay alguna forma de imponer la restricción que necesita en el nivel de Mongo, tal vez es algo que podría verificar en la lógica de la aplicación cuando inserte la actualización.

Garantizar la singularidad de los valores individuales en un campo de matriz

Además del ejemplo anterior, hay una función en MongoDB para garantizar que cuando agregue un nuevo objeto / valor a un campo de matriz, solo realice la actualización si el valor / objeto no existe.

Entonces, si tienes un documento que se ve así:

 { _id: 123, kittens: [456] } 

Esto estaría permitido:

 db.cats.update({_id:123}, {$push: {kittens:456}}) 

Resultando en

 { _id: 123, kittens: [456, 456] } 

sin embargo, el uso de la función $ addToSet (a diferencia de $ push ) verificaría si el valor ya existe antes de agregarlo. Entonces, comenzando con:

 { _id: 123, kittens: [456] } 

luego ejecutando:

 db.cats.update({_id:123}, {$addToSet: {kittens:456}}) 

No tendría ningún efecto.

Por lo tanto, para abreviar, las restricciones únicas no validan la singularidad dentro de los elementos de valor de un campo de matriz, solo que dos documentos no pueden tener valores idénticos en los campos indexados.

Hay un equivalente de inserción con uniquness en el atributo de matriz. El siguiente comando esencialmente se inserta mientras se asegura la exclusividad de los gatitos (upsert lo crea por usted si el objeto con 123 no existe).

 db.cats.update( { id: 123 }, { $addToSet: {kittens: { $each: [ 456, 456] }}, $set: {'otherfields': 'extraval', "field2": "value2"}}, { upsert: true} ) 

El valor resultante del objeto será

 { "id": 123, "kittens": [456], "otherfields": "extraval", "field2": "value2" }