Reputation: 871
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.
Upvotes: 1
Views: 250
Reputation: 11477
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.
Upvotes: 1