質問

I have a document like this:

{
    "_id" : ObjectId("534527e489e46c16787bda0f"),
    "packages" : [
        {
            number: 1
        },
        {
            number: 2
        }
    ]
}

I want to increment all packages.number at once. Is it possible?

I tried this db.collection.update({}, {$inc: {"packages.number": 1}}) but didn't work.

役に立ちましたか?

解決

No it isn't possible and the reason is given in the use of the positional $ operator. And this says that even when used you will only ever get the first match found.

So something you did not do was try to match something in the array, in which you get a value in the positional operator to use as an index as in:

db.collection.update(
    { "packages.number": 1 },
    { "$inc": { "packages.$.number": 1 } }
)

But in general you cannot update all members of an array at once, you can only retrieve the document and then update in your client code before writing back.

他のヒント

You can do like this.

// Store document in Array
temp = db.collection.find().toArray()

// Iterate Array and update the number
temp[0].packages.forEach(function(x){x.number += 1})

// Save the updated array in Collection
db.collection.save(temp[0])

This will update the required document

In the shell you can run a command like this using cursor.forEach to loop through the array elements and increment each:

> db.collection.find().forEach(function(doc){   
...   doc.packages.forEach(function(elem){elem.number+=1});   
...   db.collection.update({_id:doc._id}, {$set:{packages:doc.packages}}) 
... })

this is possible, since mongodb allows multiple fields increment:

{ $inc: { field1: amount1, field2: amount2, ... } }

and arrays are treated as different fields:

"packages.0.number" // which is 1 "packages.1.number" // 2

you can do

db.collection.findOneAndUpdate(
    { "_id" : ObjectId("534527e489e46c16787bda0f") },
    {
        "$inc": {
            "packages.0.number": 1, // which is 1
            "packages.1.number": 1 // 2
            //... and so on, you might want a loop to build the updates
        }
    }
)

Since version 3.6 you can use the $[] operator:

db.collection.update({}, {$inc: {"packages.$[].number": 1}})

Note that if you would like to update all array elements in multiple documents you need to add the { multi: true } optional argument:

db.collection.update({}, {$inc: {"packages.$[].number": 1}}, { multi: true })

See the documentation for more details:

https://docs.mongodb.com/manual/reference/operator/update/positional-all/#update-all-documents-in-an-array

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top