¿Puedes especificar una clave para $addToSet en Mongo?

Resuelto nickponline asked hace 11 años • 2 respuestas

Tengo un documento:

{ 'profile_set' :
  [
    { 'name' : 'nick', 'options' : 0 },
    { 'name' : 'joe',  'options' : 2 },
    { 'name' : 'burt', 'options' : 1 }
  ] 
}

y me gustaría agregar un nuevo documento al profile_setconjunto si el nombre aún no existe (independientemente de la opción).

Entonces, en este ejemplo, si intentara agregar:

{'name' : 'matt', 'options' : 0}

debería agregarlo, pero agregando

{'name' : 'nick', 'options' : 2}

No debería hacer nada porque ya existe un documento con nombre nickaunque optionsea diferente.

Mongo parece coincidir con todo el elemento y termino comprobando si es el mismo y termino con

profile_set containing [{'name' : 'nick', 'options' : 0}, {'name' : 'nick', 'options' : 2}]

¿Hay alguna manera de hacer esto $addToSeto tengo que presionar otro comando?

nickponline avatar Jan 26 '13 01:01 nickponline
Aceptado

Puede calificar su updatecon un objeto de consulta que impida la actualización si nameya está presente en profile_set. En el caparazón:

db.coll.update(
    {_id: id, 'profile_set.name': {$ne: 'nick'}}, 
    {$push: {profile_set: {'name': 'nick', 'options': 2}}})

Por lo tanto, esto solo se realizará $pushpara un documento que coincida _idy donde no haya un profile_setelemento donde nameesté 'nick'.

JohnnyHK avatar Jan 25 '2013 18:01 JohnnyHK

A partir de MongoDB 4.2 hay una manera de hacer esto usando expresiones de agregación en update .

Para su caso de ejemplo, haría esto:

newSubDocs = [ {'name' : 'matt', 'options' : 0}, {'name' : 'nick', 'options' : 2} ];
db.coll.update( { _id:1 },
[ 
   {$set:  { profile_set:  {$concatArrays: [ 
      "$profile_set",  
      {$filter: {
             input:newSubDocs, 
             cond: {$not: {$in: [ "$$this.name", "$profile_set.name" ]}} 
      }}
   ]}}}
])
Asya Kamsky avatar Dec 02 '2020 16:12 Asya Kamsky