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

IT技术 javascript firebase google-cloud-firestore
2021-02-18 08:36:44

遵循 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"
})

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

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

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

我一直在尝试这样做:

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

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

5个回答

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

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

db.collection("users").doc("frank").update(usersUpdate);
为什么无效?您可以在 es6 中使用反引号。这个解决方案仍然有效,它与下面的答案非常相似。developer.google.com/web/updates/2015/01/ES6-Template-Strings
2021-04-21 08:36:44
我想知道这是否真的有效。我希望它usersUpdate用一个新的值覆盖当前值,即{favorites {KEY: {color: true}}}.如果你说的是正确的,那么将没有办法实际更新usersUpdate到一个全新的值。
2021-04-22 08:36:44
这个解决方案是错误的,因为这将创建一个带有孩子收藏夹的类型映射的新字段 usersUpdate。${key}.color : true - 如果 key=1234 然后 usersUpdate 字段看起来像 usersUpdate { favorites.1234.color : true }
2021-05-06 08:36:44
2021-05-11 08:36:44
更简单地说,@Georg Hackenberg 指出了这个解决方案: db.collection('users').doc('frank').update({ [`favorites.${key}.color`] = true })
2021-05-15 08:36:44

这个解决方案对我有用:

db.collection('users').doc('frank').update({
  [`favorites.${key}.color`]: true
});
这个解决方案是正确的。另一个替代解决方案:db.collection('users').doc('frank').update({ [`favorites.${key}.color `]: true }) 还要小心避免在 [``] 部分内出现空格,即如果包含空格,您最终会做错db.collection('users').doc('frank').update({ [` favorites.${key}.color `]: true }
2021-04-15 08:36:44
虽然不做任何嵌套的东西:/只是更新
2021-04-15 08:36:44
正确的解决方案。
2021-04-26 08:36:44
潜伏者注意:这适用于更新,但对于设置,它保存为名称中带有点的单个道具,而不是作为嵌套属性。
2021-04-28 08:36:44
db.collection('users').doc('frank').update({ [` 收藏夹.${key}.color `]: true })
2021-05-05 08:36:44

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

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

不幸的是,这不起作用——它设置了一个属性,其键是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 } } }
你让我的一天,我有同样的问题很长一段时间🥰
2021-05-04 08:36:44
笏。他们什么时候变成了忍者?我敢肯定它并不总是这样。它曾经进行过浅层合并 IIRC。但是,嘿,它非常有用,所以感谢您写下它!👍🏻
2021-05-14 08:36:44

您可以更新变量(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

这是一般用途最有用的答案。谢谢你的协助。
2021-04-30 08:36:44

我觉得这是上述所有解决方案中最简单的解决方案:)

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