簡體   English   中英

如何更新 object 內部的陣列,陣列 mongoDB

[英]How to update array inside object, inside array mongoDB

所以文檔包含一個對象數組,每個 object 包含它自己的數組。 那么我將如何更新 go 來更新另一個數組中的 object 中的數組中的一個元素。 我用 $ 讀過一些東西。 但我完全不明白如何使用它來調用 position。 我知道元素的position。 但我不能只說 $[] 因為 position 是在變量而不是字符串中定義的......

我試過做一個簡單的

db.collection.findOne({...}, (err, data) => {...});

然后用一個簡單的方法更改數組中對象中的 arrays :

data.arr[x].type[y] = z; data.save().catch(err => {console.log(err)});

但它不會保存我為數組元素設置的新值。

@Tom Slabbaert 提出的解決方案后的示例結構:

Data.findOne({
    userID: 'CMA'
}, (err, doc) => {
    if(err) {console.log(err)}
    if(doc) {
        for(var i = 0; i<CMA.stockMarket.length; i++) {
            if(CMA.stockMarket[i].name == data.userID) {
                for(var z = 0; z<CMA.stockMarket[i].userStock.length; z++) {
                    if(z == company) {
                        var updateAmount = CMA.stockMarket[i].userStock[z]+args[1]
                        var updateKey = `stockMarket.${i}.userStock.${z}`
                        Data.updateOne({userID: 'CMA'}, {'$set': {[updateKey]: updateAmount}})
                    }
                }
            }
        }
    }
});

- - - - - - - - - - - - -編輯 - - - - - - - - - - - - -
所以我嘗試改變數據庫中的一些東西,看看是否能解決我遇到的問題。 我修改了@Tom Slabbaert 提供的更新代碼。 但是由於某種原因似乎沒有任何效果:/這是我到目前為止所擁有的,在這一點上,我希望這只是某個地方的語法錯誤。 因為在這一點上這真的很令人沮喪。 請注意,我仍然在這里使用 for 循環來查找信息是否存在。 如果沒有,將該信息推送到數據庫中。 這可能只是暫時的,直到我找到更好的方法/如果有更好的方法。

for(var i = 0; i<CMA.userStocks.length; i++) {
    if(CMA.userStocks[i].name == data.userID) {
        for(var z = 0; z<CMA.userStocks[i].shares.length; z++) {
            //console.log(CMA.userStocks[i].shares[z].companyName)
            if(CMA.userStocks[i].shares[z].companyName == args[0]) {
                var updateKey = `CMA.userStocks.$[elem1].shares.$[elem2].amount`

                Data.updateOne(
                    {userID: 'CMA'},
                    {
                        "$inc": {
                            [updateKey]: args[1]
                        }
                    },
                    {
                        arrayFilters: [
                            {
                                "elem1.name": data.userID,
                                "elem2.companyName": args[0]
                            }
                        ]
                    }
                )
                purchaseComplete(); return;
            }
        }
        CMA.userStocks[i].shares.push({companyName: args[0], amount: parseInt(args[1])})
        CMA.save().catch(err => {console.log(err)});
        purchaseComplete(); return;
    }
}
CMA.userStocks.push({name: data.userID, shares: [{companyName: args[0], amount: parseInt(args[1])}]});
CMA.save().catch(err => {console.log(err)});
purchaseComplete(); return;

我試圖查找和更改的數據結構如下:
我最終要改變的是“金額”(這是一個整數)

_id: (Not relavent in this question)
userID: 'CMA'
stockMarket: [...] (Not relavent in this question)
userStocks: [
   Object: (position 0 in userStocks array)
      name: 'string' (equal to data.userID in the code)
      shares: [
          Object: (position 0 in shares array)
              companyName: 'string' (this is args[0] in the code)
              amount: integer
      ]
]

你可以提前准備好“鑰匙”。 像這樣:

const updateKey = `arr.${x}.type.${y}`
db.collection.updateOne(
{...},
{
  "$set": {
    [updateKey]: z
  }
})

蒙戈游樂場

當您不知道數組中的 position 並且想要使用條件來更新元素時,通常需要使用 Mongo 的位置運算符( $$[] )。

好吧,我發現了一些有用的東西。 顯然它沒有保存db.collection.updateMany除非我最后做了 a.then() function? 我不知道為什么,但我做的聚合是一樣的。 (它基本上與 Data.findOne 相同並保存它,但它不受並行保存錯誤的限制)
我通過聚合找到的解決方案:

<collection field> = <new data for collection field>
Data.aggregate([
    {
        $match: { //This is used to create a filter
            ['<insert field>']: <insert filter>
        }
    }, {
        $addFields: { //This is used to update existing data, or create a new field containing the data if the field isn't found
            ['<collection field>']: <new data for collection field>
        }
    }, {
        $merge: { //This is used to merge the new data / document with the rest of the collection. Thus having the same effect as a standard save
            into: {
                db: '<insert database name>',
                coll: '<insert collection name>'
            }
        }
    }
]).then(() => {
    //After it's done, do something here. Or do nothing at all it doesn't matter as long as the .then() statement remains. I found that not having this part will break the code and make it not save / work for some reason.
}); return;

我用 db.collection.updateMany 找到的解決方案

db.collection.updateMany(
    {<insert field>: filter}, {$set: {'<insert field>': <new data>}}
).then(() => {
    //This .then() statment in my case was needed for the updateMany function to work correctly. It wouldn't save data without it for some reason, it does not need to contain any actual info in this part. As long as it's here.
});

有了這些新信息,我可以簡單地訪問和更改我在使用@Tom Slabbaert 提供的先前說明之前嘗試的數據以及我實際使其保存所做更改的新方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM