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

Bri*_*euc 39 javascript firebase google-cloud-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"
})
Run Code Online (Sandbox Code Playgroud)

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

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

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

我一直试图这样做:

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

它实际上是使用正确的密钥更新,但遗憾的是,它正在覆盖其他密钥(它们正被删除).

Bri*_*euc 62

我发现解决方案受到firebase解决方案的启发(将"/"替换为".").

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

db.collection("users").doc("frank").update(usersUpdate);
Run Code Online (Sandbox Code Playgroud)

  • 相关文档 - > https://firebase.google.com/docs/firestore/manage-data/add-data?authuser=0#update_fields_in_nested_objects (2认同)
  • 我想知道这是否真的有效。我希望它用具有单个值的新值覆盖 `usersUpdate` 的当前值,即 `{favorites {KEY: {color: true}}}`。如果你说的是正确的,那么就不会有实际将“usersUpdate”更新为全新值的方法。 (2认同)
  • 更简单地说,@ Georg Hackenberg指出了以下解决方案:db.collection('users')。doc('frank')。update({[\`favorites。$ {key} .color \`] = true})` (2认同)
  • 这个解决方案是错误的,因为这将创建一个带有子收藏夹的类型映射的新字段 usersUpdate。${key}.color : true - 如果 key=1234 那么 usersUpdate 字段将类似于 ```usersUpdate { favorites.1234.color : true } ``` (2认同)

小智 23

这个解决方案对我有用:

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

  • 潜伏者注意:这适用于更新,但对于设置,它保存为名称中带有点的单个道具,而不是作为嵌套属性。 (4认同)
  • 正确的解决方案。 (3认同)
  • 这个解决方案是正确的。还有替代解决方案: ```db.collection('users').doc('frank').update({ [`favorites.${key}.color `]: true })``` 并且也要足够小心避免 [``] 部分内出现空格,即如果包含空格,您最终会做错```db.collection('users').doc('frank').update({ [` favorites.${ key}.color `]: true }``` (3认同)

und*_*ned 19

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

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

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

幸运的是,它似乎进行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 } } }
Run Code Online (Sandbox Code Playgroud)