Rubén, parte de este gran equipo, nos hizo el favor de crear este artículo porque controla muy bien el tema.
Solución:
La respuesta aceptada por Flying Fisher es que el registro existente primero se eliminará y luego se volverá a enviar.
Un enfoque más seguro (sentido común) sería tratar de actualizar el registro primero, y si eso no encuentra una coincidencia, insértelo, así:
// first try to overwrite existing value
var result = db.collection.update(
_id : ObjectId("57315ba4846dd82425ca2408"),
"myarray.userId": ObjectId("570ca5e48dbe673802c2d035")
,
$set: "myarray.$.point": point: 10
);
// you probably need to modify the following if-statement to some async callback
// checking depending on your server-side code and mongodb-driver
if(!result.nMatched)
// record not found, so create a new entry
// this can be done using $addToSet:
db.collection.update(
_id: ObjectId("57315ba4846dd82425ca2408")
,
$addToSet:
myarray:
userId: ObjectId("570ca5e48dbe673802c2d035"),
point: 10
);
// OR (the equivalent) using $push:
db.collection.update(
_id: ObjectId("57315ba4846dd82425ca2408"),
"myarray.userId": $ne: ObjectId("570ca5e48dbe673802c2d035"
,
$push:
myarray:
userId: ObjectId("570ca5e48dbe673802c2d035"),
point: 10
);
}
Esto también debería dar (sentido común, no probado) un aumento en el rendimiento, si en la mayoría de los casos el registro ya existe, solo se ejecutará la primera consulta.
Prueba esto
db.collection.update(
_id : ObjectId("57315ba4846dd82425ca2408"),
$pull: "myarray.userId": ObjectId("570ca5e48dbe673802c2d035")
)
db.collection.update(
_id : ObjectId("57315ba4846dd82425ca2408"),
{ $push: "myarray":
userId:ObjectId("570ca5e48dbe673802c2d035"),
point: 10
)
Explicación: en la primera declaración $pull
elimina el elemento con userId= ObjectId("570ca5e48dbe673802c2d035")
desde el array en el documento donde _id = ObjectId("57315ba4846dd82425ca2408")
en el segundo $push
inserta este objeto userId:ObjectId("570ca5e48dbe673802c2d035"), point: 10
en el mismo array.
Desafortunadamente, la operación “upsert” no es posible en incrustados array. Los operadores simplemente no existen, por lo que esto no es posible en una sola declaración. Por lo tanto, debe realizar dos operaciones de actualización para hacer lo que desea. Además, el orden de aplicación de estas dos actualizaciones es importante para obtener el resultado deseado.
Comentarios y calificaciones
Agradecemos que quieras añadir valor a nuestro contenido asistiendo con tu experiencia en las referencias.