Tengo un documento que contiene una propiedad de matriz que tiene elementos de objeto.
P.EJ
{ "_id": "61c01098bc29520008efc00f", "name": "codedump", "employments": [ { "type": "PERMANENT", "salary": 1000000000 }, { "type": "TEMP", "salary": 1000000000 }, { "type": "PART_TIME", "salary": 1000000000 }, ] } Y mientras actualizo el salario de empleo usando el type si el tipo ya está en empleos, solo necesito actualizar el salary . De lo contrario, necesito empujar el nuevo elemento a la matriz. Estoy tratando de encontrar una manera de hacer que esto funcione en una sola consulta.
/// Update data: { "type": "PERMANENT", "salary": 10 } // For this case I want the example document to become: { "_id": "61c01098bc29520008efc00f", "name": "codedump", "employments": [ { "type": "PERMANENT", "salary": 10 // From 1000000000 to 10 }, { "type": "TEMP", "salary": 1000000000 }, { "type": "PART_TIME", "salary": 1000000000 }, ] } /// Update data: { "type": "INVESTMENT", "salary": 10000 } // For this case I want the example document to become: { "_id": "61c01098bc29520008efc00f", "name": "codedump", "employments": [ { "type": "PERMANENT", "salary": 1000000000 }, { "type": "TEMP", "salary": 1000000000 }, { "type": "PART_TIME", "salary": 1000000000 }, { "type": "INVESTMENT", "salary": 10000 } ] }Es técnicamente posible en 1 llamada, a partir de Mongo v4.2 puede usar actualizaciones canalizadas , esto esencialmente le permite usar operadores de agregación en el cuerpo de la actualización, por lo que puede lograr prácticamente cualquier cosa.
Sin embargo, diré que definitivamente no es muy eficiente, realmente depende de qué parte de su sistema desea maximizar / minimizar (red / carga de db / etc.).
Así es como puedes hacerlo:
const input = { "type": "INVESTMENT", "salary": 10000 } db.collection.update({}, [ { $set: { employments: { $cond: [ { $in: [ input.type, "$employments.type" ] }, { $map: { input: "$employments", in: { $cond: [ { $eq: [ "$$this.type", input.type, ] }, { type: "$$this.type", salary: input.salary }, "$$this" ] } } }, { $concatArrays: [ "$employments", [ input ] ] } ] } } } ])No sé si lo que buscas es posible en una sola operación...
Dicho esto, cómo lo haría es usar el operador posicional $ para actualizar el elemento de matriz que quiero. Doc y parque infantil .
db.collection.update({ "employments.type": "PERMANENT", }, { "$set": { "employments.$.salary": 10 } }, { "multi": false, "upsert": false }) Esta operación solo funcionaría si el elemento existe en la matriz. Si no es así, la operación fallaría. Luego puede capturar la excepción en su código y realizar una inserción con $push . Patio de recreo
db.collection.update({}, { "$push": { "employments": [ { "type": "INVESTMENT", "salary": 10000 } ] } }, { "multi": false, "upsert": false })