1

I am wondering how can I change the element in such array in Mongo DB. Say the collections is as follow:

{
"_id" : ObjectId("xxxxxxxxxxxxxxxx"),

"user_info" : {
    "user_name" : "joe",        
},

"portfolio" : [ 
    {
        "market_symbol" : "NASDAQ:GOOGL",
        "details" : [ 
            {
                "amount" : 100,
                "purchased_price" : 810.25,
                "date_of_purchase" : "20170210 212426"
            }, 
            {
                "amount" : 100,
                "purchased_price" : 810.25,
                "date_of_purchase" : "20170210 212426"
            }, 
            {
                "amount" : 200,
                "purchased_price" : 900.0,
                "date_of_purchase" : "20170210 212426"
            }
        ]
    }, 
    {
        "market_symbol" : "NYSE:BABA",
        "details" : [ 
            {
                "amount" : 200,
                "purchased_price" : 80.0,
                "date_of_purchase" : "20170210 212426"
            }, 
            {
                "amount" : 333,
                "purchased_price" : 86.11,
                "date_of_purchase" : "20170210 212426"
            }
        ]
    }
]

I am trying to modify the value of amount in "portfolio:market_symbol":"NASDAQ:GOOGL", where the purchased_price is 900 and I want to set the 200 to 300.

so the segment should look like this after the modification:

"portfolio" : [ 
{
    "market_symbol" : "NASDAQ:GOOGL",
    "details" : [ 
        {
            "amount" : 100,
            "purchased_price" : 810.25,
            "date_of_purchase" : "20170210 212426"
        }, 
        {
            "amount" : 100,
            "purchased_price" : 810.25,
            "date_of_purchase" : "20170210 212426"
        }, 
        {
            "amount" : 300,
            "purchased_price" : 900.0,
            "date_of_purchase" : "20170210 212426"
        }
    ]
}, 

I tried to use $elemMatch in mongo shell

db.Users.update({"user_info.user_name":"joe","portfolio":{$elemMatch:{"market_symbol":{$eq:"NASDAQ:GOOGL"},"details.purchased_price":{$eq:900}}}},{$set:{"portfolio.$.details.0.amount":300}})

It seems that the query always return the entire section of "portfolio:market_symbol":"NASDAQ:GOOGL", because the 0 in {$set:{"portfolio.$.details.0.amount":300}} modifies the first array in details, whose purchased_price is 810.25, rather than what I expect the $elemMatch to give me (the 3rd element from the array, whose purchased_price is 900).

Is there a way that I can modify this nested nested array, rather than pulling the entire thing off, modify the data in my program, then write the entire thing back?

Please help, thanks.

1 Answer 1

1

As far as I know,the positional operator only supports one level deep and only the first matching element.So that means updating all documents in array is not possible now.

There is a MongoDB JIRA ticket: https://jira.mongodb.org/browse/SERVER-831

But you can update specific document manually.

db.test.find( 
{ "user_info.user_name":"joe", "portfolio.details.purchased_price" : 900.0 }).forEach(function(doc) { 
  doc.portfolio.forEach(function(item) { 
      item.details.forEach(function (amt){
            if (amt.purchased_price == 900.0)
                amt.amount=300
          });
      });
  db.test.update( { "user_info.user_name":"joe", "portfolio.details.purchased_price" : 900.0 }, { "$set": { "portfolio": doc.portfolio } });
});

It works for me.Hope this helps.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.