Actualizar campo en matriz de elementos exactos en MongoDB

Resuelto Denis Ermolin asked hace 12 años • 5 respuestas

Tengo un documento estructurado así:

{
    _id:"43434",
    heroes : [
        { nickname : "test",  items : ["", "", ""] },
        { nickname : "test2", items : ["", "", ""] },
    ]
}

¿ Puedo colocar $setel segundo elemento de la itemsmatriz del objeto incrustado en una matriz heroscon nickname "test"?

Resultado:

{
    _id:"43434",
    heroes : [
        { nickname : "test",  items : ["", "new_value", ""] }, // modified here
        { nickname : "test2", items : ["", "", ""] },
    ]
}
Denis Ermolin avatar May 03 '12 20:05 Denis Ermolin
Aceptado

Debes utilizar 2 conceptos: el operador posicional de mongodb y simplemente usar el índice numérico para la entrada que deseas actualizar.

El operador posicional le permite utilizar una condición como esta:

{"heroes.nickname": "test"}

y luego haga referencia a la entrada de la matriz encontrada de esta manera:

{"heroes.$  // <- the dollar represents the first matching array key index

Como desea actualizar la segunda entrada de la matriz en "elementos", y las claves de la matriz están indexadas en 0, esa es la clave 1.

Entonces:

> db.denis.insert({_id:"43434", heroes : [{ nickname : "test",  items : ["", "", ""] }, { nickname : "test2", items : ["", "", ""] }]});
> db.denis.update(
    {"heroes.nickname": "test"}, 
    {$set: {
        "heroes.$.items.1": "new_value"
    }}
)
> db.denis.find()
{
    "_id" : "43434", 
    "heroes" : [
        {"nickname" : "test", "items" : ["", "new_value", "" ]},
        {"nickname" : "test2", "items" : ["", "", "" ]}
    ]
}
AD7six avatar May 03 '2012 14:05 AD7six

Intente actualizar el documento en una matriz usando $ posicional ,

El operador posicional $ facilita las actualizaciones de matrices que contienen documentos incrustados. Utilice el operador $ posicional para acceder a los campos de los documentos incrustados con la notación de puntos en el operador $.

db.collection.update(
  { "heroes.nickname": "test" },
  { $set: { "heroes.$.items.1": "new_value" } },
  { multi: true }
);

Patio de juegos

turivishal avatar Apr 23 '2021 10:04 turivishal

Esta solución funciona bien. Sólo quiero agregar un punto. Aquí está la estructura. Necesito encontrar que OrderItemId sea 'yyy' y actualizarlo. Si el campo de consulta en condición es una matriz, como debajo "OrderItems.OrderItemId" es una matriz. No puede utilizar "OrderItems.OrderItemId[0]" como operación en la consulta. En su lugar, debe utilizar "OrderItems.OrderItemId" para comparar. De lo contrario, no podrá coincidir con ninguno.

{
  _id: 'orderid',
  OrderItems: [
   {
     OrderItemId: ['xxxx'], 
    ... },
   {
     OrderItemId: ['yyyy'], 
    ...}, 
]

}
 result =  await collection.updateOne(
        { _id: orderId, "OrderItems.OrderItemId": [orderItemId] },
        { $set: { "OrderItems.$.imgUrl": imgUrl[0], "OrderItems.$.category": category } },
        { upsert: false },
      )
    console.log('  (result.modifiedCount) ', result.modifiedCount)
    console.log('  (result.matchedCount) ', result.matchedCount)
Kathy avatar Apr 17 '2019 04:04 Kathy

Intente actualizar con $ posicional y $position ,

db.collection.update(
  { heroes:{ $elemMatch:{ "nickname" : "test"} } },
  {
    $push: {
      'heroes.$.items': {
        $each: ["new_value" ],
        $position: 1
      }
    }
  }
)
Rubin Porwal avatar Oct 11 '2018 13:10 Rubin Porwal