簡體   English   中英

如何動態更新mongodb中的嵌套對象

[英]how to dynamically update the nested objects in mongodb

我們有一些任意嵌套的配置存儲在 mongodb 中。

  1. 假設我們最初將以下對象存儲在 mongodb 中。

const value = { 'a': { 'b': 1 } }

collection.insertOne({userId, value})

現在我想通過添加來修改數據庫中的對象

const addValue = { 'f': { 'c': 2 } }

類似的還有更多的嵌套對象。

const addValue1 = { 'a': { 'd': 1 }, 'f': { 'g': 1 } };

正如我們添加的那樣,這些keys是非常動態的,應該能夠更新數據庫中的值但不能替換它,因此期望存儲的最終結果應該是

const result = collection.findOne({ userId });

console.log(result);

{ 'a': { 'b': 1, 'd': 1 }, 'f': { 'g': 1, 'c': 2 } }

如果 udpate 值為

const addValue2 = { 'a': { 'b' : { 'e': 1 } } }

預期結果是

const result2 = { 'a': { 'b': { 'e': 1 } , 'd': 1 }, 'f': { 'g': 1, 'c': 2 } }

刪除的時候也一樣

    let testObject = new MongoDBStorageService('test', dbConnection as any, 'userTestSchema');

    testObject.load({ 'a': { 'b': 1 }});
    testObject.removeValue('a.b');

    const content = await testObject.contents;

 expect(content).toEqual({}); // but we see output as `{ a: {} }`

使用的刪除方法

public async removeValue(key: string) {
        return await this.remove(JSON.parse(`{\"${key}\": "" }`));
    }
private remove(value) {
    return new Promise((resolve, reject) => {
        this.collection.updateOne({ user: this.userId }, {
            $unset: value,
        }, { upsert: false }, function (err, res) {
            if (err) {
                reject(err);
            } else {
                console.log('REUSLL AFTER REMOVE', res.);
                resolve({ id: true });
            }
        });
    });
}

這里的困難在於您必須將對象轉換為 MongoDB 的點表示法,它可用於構建更新語句。 您可以通過運行以下函數來做到這一點:

 let flatten = (obj, prefix, result) => { result = result || {}; for(let key of Object.keys(obj)){ let keyExpr = prefix ? `${prefix}.${key}` : `${key}`; if(typeof obj[key] === "object"){ flatten(obj[key], keyExpr, result); } else { result[keyExpr] = obj[key]; } } return result; } const addValue = { 'f': { 'c': 2 } } let update1 = flatten(addValue) console.log(update1); const addValue1 = { 'a': { 'd': 1 }, 'f': { 'g': 1 } }; let update2 = flatten(addValue1); console.log(update2);

const value = { 'a': { 'b': 1 } }
const userId = 1;
db.col.insertOne({userId, ...value})

db.col.update({ userId: userId }, { $set: update1 });
db.col.update({ userId: userId }, { $set: update2 });

不能直接在對象上運行$set的原因是它將替換現有a嵌套對象而不是合並它。

暫無
暫無

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

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