Search code examples
arraysmongodbmongodb-querymongodb-update

MongoDB update change/convert an array with string elements to an array with object elements using the existing/current value within that object


I am learning MongoDB (5.6) and have a collection with documents like this:

[
  {
    "_id": {
      "$oid": "62642b53df03395a48eba4d3"
    },
    "title": "Chemical Biology",
    "authors": [
      "625861411edf9d62ec72c889"
    ],
    "year": 1947,
    "sentences": [
      "sentence 001",
      "sentence 002"
    ]
  }
]

I want to update the array "sentences" to an array of objects (in all the documents of the collection) using the existing value. I expect it like this:

[
  {
    "_id": {
      "$oid": "62642b53df03395a48eba4d3"
    },
    "title": "Chemical Biology",
    "authors": [
      "625861411edf9d62ec72c889"
    ],
    "year": 1947,
    "sentences": [
      {
        "order_chem": 50,
        "order_bio": 50,
        "order_science": 50,
        "order_school": 50,
        "value": "sentence 001"
      },
      {
        "order_chem": 50,
        "order_bio": 50,
        "order_science": 50,
        "order_school": 50,
        "value": "sentence 002"
      }
    ],
  }
]

So far this query is the nearest thing I have achieved:

db.collection.update({},
[
  {
    "$set": {
      "sentences": {
        "value": {"$arrayElemAt": ["$sentences", 0]},
        //"value": "$sentences",
        "order_chem": 50,
        "order_bio": 50,
        "order_science": 50,
        "order_school": 50
      }
    }
  }
],
{
  multi: true
})

Which of course is producing nearly what I want, but not exactly (since I hard quoted the index to 0). If I could gain access to the current index/value of the array sentences in each loop, I can get the desired result.

[
  {
    "_id": ObjectId("62642b53df03395a48eba4d3"),
    "authors": [
      "625861411edf9d62ec72c889"
    ],
    "sentences": [
      {
        "order_chem": 50,
        "order_bio": 50,
        "order_science": 50,
        "order_school": 50,
        "value": "sentence 001",
      },
      {
        "order_chem": 50,
        "order_bio": 50,
        "order_science": 50,
        "order_school": 50,
        "value": "sentence 001"
      }
    ],
    "title": "Chemical Biology",
    "year": 1947
  }
]

Mongo Playground

How can I access the exact numeric array index or element/content in each loop?

Thanks for your patience to read this far. Can you please advice how to use the current/existing value of a numerical array field and convert the same field to an object array using the current value?

Thanks in advance.


Solution

  • As you are working update with aggregation pipeline, you can use $map to iterate elements in sentences and return new sentences array.

    db.collection.update({},
    [
      {
        "$set": {
          "sentences": {
            $map: {
              input: "$sentences",
              in: {
                "order_chem": 50,
                "order_bio": 50,
                "order_science": 50,
                "order_school": 50,
                value: "$$this"
              }
            }
          }
        }
      }
    ],
    {
      multi: true
    })
    

    Sample Mongo Playground