1

I need to update or create if not exist, specific obj,set score.b1 =50 and total=100 where object match curse=5 block=2

{ "_id":"sad445"
  "year":2020,
  "grade":4,
  "seccion":"A",
    "id": 100,
  "name": "pedro",
  "notes":[{"curse":5, 
          "block":1, 
          "score":{ "a1": 5,"a2": 10, "a3": 15},
          "total" : 50
          },{
          "curse":5, 
          "block":2, 
          "score":{ "b1": 10,"b2": 20, "b3": 30},
          "total" : 20
          }
   ]
}

I can update all obj but I need to update or create specific elem from the score and not all. and/or create objs "notes":[{curse, block and score}] if notes is empty notes:[]

notas.UpdateMany(
{"$and":[{"_id":"sad445"},{"notes":{"$elemMatch":{"curse":5,"block":3}}}]},

{"$set":{"updated_at":{"$date":{"$numberLong":"1620322881360"}},

"notes.$.score":{"vvkzo":15,"i2z4i":2,"i2z4i|pm":5},
"notes.$.total":100}},

{"multiple":false})

2 Answers 2

3

Demo - https://mongoplayground.net/p/VaE28ujeOPx

Use $ (update)

The positional $ operator identifies an element in an array to update without explicitly specifying the position of the element in the array.

the positional $ operator acts as a placeholder for the first element that matches the query document, and

the array field must appear as part of the query document.

db.collection.update({
  "notes": {
    "$elemMatch": { "block": 2, "curse": 5 }
  }
},
{
  $set: { "notes.$.score.b4": 40 }
})

Read upsert: true

Optional. When true, update() either:

Creates a new document if no documents match the query. For more details see upsert behavior. Updates a single document that matches the query. If both upsert and multi are true and no documents match the query, the update operation inserts only a single document.

To avoid multiple upserts, ensure that the query field(s) are uniquely indexed. See Upsert with Unique Index for an example.

Defaults to false, which does not insert a new document when no match is found.


Update

Demo - https://mongoplayground.net/p/iQQDyjG2a_B

Use $function

db.collection.update(
    { "_id": "sad445" },
    [
      {
        $set: {
          notes: {
            $function: {
              body: function(notes) {
                        var record = { curse:5, block:2, score:{ b4:40 } };
                        if(!notes || !notes.length) { return [record]; } // create new record and return in case of no notes
                        var updated = false;
                        for (var i=0; i < notes.length; i++) {
                            if (notes[i].block == 2 && notes[i].curse == 5) { // check condition for update
                                updated = true;
                                notes[i].score.b4=40; break; // update here
                            }
                        }
                        if (!updated) notes.push(record); // if no update push the record in notes array
                        return notes;
                    },
              args: [
                "$notes"
              ],
              lang: "js"
            }
          }
        }
      }
    ]
)
Sign up to request clarification or add additional context in comments.

4 Comments

yes!! works but My problem is when the "notes": [] is empty, in this case, I need to create obj {"curse": 5, "block": 2, "notes":{"b4": 100} } please help me how can I do it.
@Carlos Which version of mongodb are you using ?
mongodb v 4.4.5
thanks so much!!! where are you from? and where are you studied?
0

Try to add upsert: true.

Creates a new document if no documents match the query. Updates a single document that matches the query.

notas.UpdateMany(
{"$and":[{"_id":"sad445"},{"notes":{"$elemMatch":{"curse":5,"block":3}}}]},

{"$set":{"updated_at":{"$date":{"$numberLong":"1620322881360"}},

"notes.$.score":{"vvkzo":15,"i2z4i":2,"i2z4i|pm":5},
"notes.$.total":100}},

{"multiple":false, "upsert":true})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.