Home > Enterprise >  Mongodb, use selected document value to update field in same document using single operation
Mongodb, use selected document value to update field in same document using single operation

Time:12-18

Lets say you are making a simply todo app and you have a structure that looks like this:

{
[userId]: {
  nextTaskId:3,
  tasks: {
    1: "take out the trash",
    2: "pick up milk"
  }
}

When adding a task, I'd like to create a new record using the the nextTaskId and also increment it. I have seen other examples using a aggregation function like $concat or the like, but that doesn't fit my usecase.

I'd like to be able to reference the field in my update, something like:

db.tasks.updateOne({_id:5}, {$inc:{nextId:1}, $set: {"tasks.$nextId":{"new task" }}})

the field does get incremented, however the tasks key is not 3, but $nextId and I also tried using it as a value, as in:

db.tasks.updateOne({_id:5}, {$inc:{nextId:1}, $set: {"tasks.3":{"$nextId" }}})

that doesn't work either. of course, I could do this by making 2 individual operations, one to get the next id and increment it, and another to create the new task record, but i'm hoping to do it with a single operation.

Any ideas?

CodePudding user response:

You can use update with aggregation pipeline to achieve the behaviour in one single update statement. Use $objectToArray and $arrayToObject to manipulate the tasks array.

db.collection.update({
  _id: 5
},
[
  {
    "$addFields": {
      "tasks": {
        "$objectToArray": "$tasks"
      }
    }
  },
  {
    "$addFields": {
      "nextTaskId": {
        $add: [
          "$nextTaskId",
          1
        ]
      },
      tasks: {
        "$concatArrays": [
          "$tasks",
          [
            {
              k: {
                $toString: "$nextTaskId"
              },
              // your input for the new task
              v: "next task"
            }
          ]
        ]
      }
    }
  },
  {
    "$addFields": {
      "tasks": {
        "$arrayToObject": "$tasks"
      }
    }
  }
])

Here is the Mongo playground for your reference.

  • Related