10

So I have this issue with mongodb 4.2.1 using Robo 3T. I want to update specific documents, by moving a field inside another one which is an object.

Using update() like this works fine.

db.getCollection('myCollections').update(
    {
        randomId: ObjectId("......."),
    },
    [
        { $set: { "myObject.myField": "$myField" } },
        { $unset: [ "myField" ] }
    ])

But when I want to update all my documents using updateMany() like this.

db.getCollection('myCollections').updateMany(
    {
        randomId: ObjectId("......."),
    },
    [
        { $set: { "myObject.myField": "$myField" } },
        { $unset: [ "myField" ] }
    ])

I have an error

Failed to execute script.

Error: the update operation document must contain atomic operators 
Details:
DBCollection.prototype.updateMany@src/mongo/shell/crud_api.js:625:1
@(shell):1:1

I didn't try using the shell but I suppose it will tell me the same thing.

Edit

Example of a document before

{
  _id: ...,
  randomId: ObjectId(...),
  myField: 0.5
  myObject: {
    value1: 1,
    ...
  }
  ...
}

After

{
  _id: ...,
  randomId: ObjectId(...),
  myObject: {
    value1: 1,
    myField: 0.5,
    ...
  }
  ...
}
A.Fe
  • 191
  • 1
  • 7

4 Answers4

9

My bad. I just tried with mongo shell and it works fine. Should stop using robo 3T for update.

Sorry for the bother and thanks for the answers

A.Fe
  • 191
  • 1
  • 7
2

Update the document using $rename update operator; it is just renaming the field.

db.upd.updateOne(
  { randomId: ObjectId("xyz")},
  { $rename: { myField: "myObject.myField" } }
}
prasad_
  • 12,755
  • 2
  • 24
  • 36
2

This is to help people who did the same mistake of leaving $set like me.

So it gave me the same error message specified in the question.

Append $set as well in the query.

Before:

db.myData.updateOne({key:"value"},{key:"new-value"})

After:

db.myData.updateOne({key:"value"},{$set:{key:"new-value"}}) 

Then I was able to update my data.

JON
  • 965
  • 2
  • 10
  • 28
adi
  • 984
  • 15
  • 33
-1

The second parameter of updateOne() and updateMany() must by an Object, so basically you are using a wrong syntax, try like this instead:

db.getCollection('myCollections').updateMany({
    randomId: ObjectId("......."),
}, {
    $set: {
        "myObject.myField": "$myField"
    },
    $unset: {
        "myField": 1
    }
})
Matheus Hatje
  • 987
  • 1
  • 7
  • 18
  • 1
    So the update works fine but instead of `myField` value in `myObject.myField`, I have a string `$myField` for all updated documents. For the second parameter of `updateMany`, I wanted to use aggregation pipeline like it was said in the docs, and you need to use this syntax: `[ , ... ]`. Seems like the only way to get `myField` value is to use aggregation pipeline. – A.Fe Nov 20 '19 at 16:47
  • Sorry for the lack of understanding, but what exactly are you trying to achieve? – Matheus Hatje Nov 20 '19 at 16:54
  • No problem :D. I just updated my question with some examples for what I want to do. – A.Fe Nov 20 '19 at 17:03