Javascript Cloud Firestore:使用动态键更新嵌套对象中的字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47295541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:48:16  来源:igfitidea点击:

Cloud Firestore: Update fields in nested objects with dynamic key

javascriptfirebasegoogle-cloud-firestore

提问by Brieuc

following the official documentation of firestore :

遵循 firestore 的官方文档:

{
    name: "Frank",
    favorites: { food: "Pizza", color: "Blue", subject: "recess" },
    age: 12
}

// To update favorite color:
db.collection("users").doc("frank").update({
    "favorites.color": "Red"
})

I would like to use a dynamic key instead of color.

我想使用动态键而不是颜色。

db.collection("users").doc("frank").update({
    "favorites[" + KEY + "].color": true
});

this is of course not possible and will throw an error.

这当然是不可能的,并且会抛出错误。

I've been trying to do this :

我一直在尝试这样做:

db.collection("users").doc("frank").update({
    favorites: {
        [key]: {
            color": true
        }
    }
});

It is actually updating with the right key but unfortunately, it is overwriting the other keys (they are being deleted).

它实际上是使用正确的键进行更新,但不幸的是,它正在覆盖其他键(它们正在被删除)。

回答by Brieuc

I found the solution inspired by a firebase solution (replacing "/" by ".").

我找到了受 firebase 解决方案启发的解决方案(将“/”替换为“.”)。

var usersUpdate = {};
usersUpdate[`favorites.${key}.color`] = true;

db.collection("users").doc("frank").update(usersUpdate);

回答by Georg Hackenberg

This solution worked for me:

这个解决方案对我有用:

db.collection('users').doc('frank').update({
  ['favorites.' + key + '.color']: true
});

回答by Ronnie Royston

You can update specific fields of variable(ly) named nested objects like below.

您可以更新变量(ly)命名嵌套对象的特定字段,如下所示。

ref.set({
    name: "Frank",
    favorites: { food: "Pizza", quantity: 2 }
});

//now the relevant update code
var name = "favorites";
var qty = 111;
var update = {};
update[name+".quantity"] = qty;
ref.update(update);

https://jsbin.com/hihifedizu/edit?js,console

https://jsbin.com/hihifedizu/edit?js,console

回答by undefined

Just a note about a potential pitfall: After discovering that you can update nested fields using a dot syntax, I tried using set()the same way, since I needed it to work whether the object already exists or not:

关于潜在陷阱的说明:在发现您可以使用点语法更新嵌套字段后,我尝试使用set()相同的方式,因为无论对象是否已经存在,我都需要它来工作:

var updateObj = {['some.nested.property']: 9000};
docRef.set(updateOb, {merge: true});

Unfortunately, this doesn't work – it sets a property whose key is some.nested.propertyinstead. Inconsistent, but okay.

不幸的是,这不起作用——它设置了一个属性,其键是some.nested.property。不一致,但还好。

Fortunately, it appears that set(updateObj, {merge: true})does a deep merge, so if you construct your update object as a fully nested object, your nested objects will also be properly merged:

幸运的是,它似乎进行set(updateObj, {merge: true})了深度合并,因此如果您将更新对象构造为完全嵌套的对象,您的嵌套对象也将被正确合并:

// create the object
db.doc('testCollection/doc').set({p1: {['p2']: {p3: true}}}, {merge: true})
// update the existing object
db.doc('testCollection/doc').set({p1: {['p2']: {p4: true}}}, {merge: true})

// result is now this:
{ p1: { p2: { p4: true, p3: true } } }