0

I am new at MongoDB and I want to increase the "rate2" of the "increase" array by 100%. It is located in my "CUSTOMER.ratings" document that has first name of "Jimmy".

The collection is like this:

db.collection.insert(
  {
    "CUSTOMER": {
      "first name": "Jimmy",
      "ratings": [{"increase": {"rate":99},  {"increase": {"rate2": 20.5}}]
    }
  }
); 

I tried the following, but it created a new set insted putting a new address inside the array of location:

db.collection.update({"CUSTOMER.first name": "Jimmy"}, {$mul:{"ratings":{"increase":{ "rate2": 2 }}}}); 

I tried to put the "ratings" prior to the $mul put it doesn't work.

I need the right prototype of doing such thing.

The expected outcome is the following:

db.collection.insert(
  {
    "CUSTOMER": {
      "first name": "Jimmy",
      "ratings": [{{"increase": "rate": 99}},
                   {"increase": "rate": 41}}
]
    }
  }
); 

To sum up, I want to increase rate2 by 100% .

To not be confusing, consider the following:

A 
   B[
      C {rate}
      C {rate2} ]

So how to multiply the value of "rate2"?

I tried {$mul: {"A":{"B":{"C":2 }}}}; 
Also, I tried {$mul: {"A.B.C": 2}};
Also, I tried {"A.B": {$mul: {"C": 2}}};

Also, I have used the $pull and $push prototype, but not sure why not working!!

Aki
  • 33
  • 6
  • Does this answer your question? [Updating a Nested Array with MongoDB](https://stackoverflow.com/questions/23577123/updating-a-nested-array-with-mongodb) – Joe Jun 04 '20 at 22:53
  • I tried such that but didn't work well. It just separate the document. – Aki Jun 04 '20 at 23:09
  • you tried with `{$mul:{"ratings.$[filtername].increase.rate2":2}}`? – Joe Jun 04 '20 at 23:13
  • Yes. It says " Cannot multiply with non-nmuric argument " – Aki Jun 04 '20 at 23:29
  • Perhaps use `{$type:"number"}` as part of the array filter? – Joe Jun 05 '20 at 00:11

1 Answers1

1

Consider the input document:

{
        "_id" : 1,
        "CUSTOMER" : {
                "first name" : "Jimmy",
                "ratings" : [
                        {
                                "increase" : {
                                        "rate" : 99
                                }
                        },
                        {
                                "increase" : {
                                        "rate2" : 20.5
                                }
                        }
                ]
        }
}

The following query will update the document and multiply (by 2 and update) the nested field rate2 ("CUSTOMER.ratings.increase.rate2").

db.collection.updateOne(
  { _id: 1 },
  { $mul: { "CUSTOMER.ratings.$[e].increase.rate2": 2 } },
  { arrayFilters: [ { "e.increase.rate2": { $exists: true } } ] }
)

Note the usage of the arrayFilters and the filtered positional operator $[some_id] (which is used to update specific array elements as mentioned in the arrayFilters condition).


[EDIT ADD]

Another way of updating: Updating using the positional $ update operator:

db.collection.updateOne(
  { "CUSTOMER.ratings.increase.rate2": { $exists: true } },
  { $mul: { "CUSTOMER.ratings.$.increase.rate2": 2 } }
)
prasad_
  • 12,755
  • 2
  • 24
  • 36
  • You are right. I tried such code but my only mistake was not adding the "$" symbol. Could you tell me why adding $, in between, is matter in such requirement? Because it works without the arrayFilter. I just add the symbol and it worked well. – Aki Jun 05 '20 at 02:20
  • You can use the [positional $ update operator](https://docs.mongodb.com/manual/reference/operator/update/positional/) too. But, you must specify the condition on the array filed in the update method's query filter. Note this update _only_ modifies the _first_ matching array element. – prasad_ Jun 05 '20 at 03:05
  • I had tried this which is without the $ symbol; db.collection.update({$mul:{ "CUSTOMER.ratings.increase.rate2": 2 }}); – Aki Jun 05 '20 at 23:26
  • I had tried this which is without the $ symbol; db.collection.update({" CUSTOMER.ratings.increase.rate2" : 21.5}, {$mul:{ "CUSTOMER.ratings.increase.rate2": 2 }}); – Aki Jun 05 '20 at 23:34