Mongo DB修改嵌套数组中的元素

时间:2017-02-11 22:33:23

标签: arrays mongodb mongo-shell

我想知道如何在Mongo DB中更改此类数组中的元素。说集合如下:

{
"_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"
            }
        ]
    }
]

我正在尝试修改其值 amount中的"portfolio:market_symbol":"NASDAQ:GOOGL",其中purchased_price900,我想将200设置为300。

因此修改后片段应如下所示:

"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"
        }
    ]
}, 

我尝试在mongo shell中使用$elemMatch

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}})

似乎查询始终返回"portfolio:market_symbol":"NASDAQ:GOOGL"的整个部分,因为0中的{$set:{"portfolio.$.details.0.amount":300}}修改了details中的第一个数组,其purchased_price810.25,而不是我期望$elemMatch给我的(数组中的第3个元素,purchased_price900)。

有没有办法可以修改这个嵌套的嵌套数组,而不是拉掉整个东西,修改程序中的数据,然后把整个东西写回来?

请帮助,谢谢。

1 个答案:

答案 0 :(得分:1)

据我所知,位置运算符只支持一级深度,只支持第一个匹配元素。这意味着现在无法更新数组中的所有文档。

有一张MongoDB JIRA票证:https://jira.mongodb.org/browse/SERVER-831

但您可以手动更新特定文档。

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 } });
});

它对我有用。希望这有帮助。