云 Firestore:使用点表示法更新嵌套数组对象中的字段值
云 Firestore:使用点表示法更新嵌套数组对象中的字段值
请帮我解决这个问题,我想使用点表示法和set()方法来更新字段,但是每次运行下面的实现时,我在Firestore中添加的字段是studentInfo.0.course.0.courseId
,而不是更新已经存在的字段。
Firestore中的JSON示例:
"schoolId": "school123",
"studentInfo": [
{
"studentId": "studentI23",
"regDate": "2020-04-18",
"course": [
{
"courseId": "cs123",
"regDate": "2020-05-28",
"status": "COMPLETED"
}
]
}
],
"registered":"yes"
}
代码逻辑:
const query = firestore.collection('users').where('registered', '==', 'yes') const students = await query.get() students.forEach(student => { firestore.doc(student.ref.path).set({ 'studentInfo.0.studentId': '345','studentInfo.0.course.0.courseId': '555' }, { merge: true }) })
在文档https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects中,我只能找到更新嵌套对象的方法,而没有关于更新嵌套数组对象的说明。
问题的出现原因是在Cloud Firestore中,无法使用点符号或其他方式来更新数组中的单个元素。要更新数组,需要进行以下步骤:读取文档、获取数组的当前值、确定新的数组内容、将整个更新后的数组写回数据库。而唯一的替代数组操作是array-union
和array-remove
,它们用于将唯一元素添加到数组中或从数组中删除元素,实质上将其视为数学集合。但是,由于您想要更新现有元素,这些操作在这里无用。感谢提供清晰的回复和相关链接,我对此感到非常困惑,以为自己漏掉了什么。但显然,更新数组中的单个元素非常麻烦。
解决方法是阅读文档,获取数组的当前值,确定新的数组内容,然后将整个更新后的数组写回数据库。以下是一些相关的链接供参考:
- [Firestore Update single item in an array field](https://stackoverflow.com/questions/52187985)
- [Firestore update specific element in array](https://stackoverflow.com/questions/53319529)
- [How to update an "array of objects" with Firestore?](https://stackoverflow.com/questions/46757614)
以上是关于在Cloud Firestore中使用点符号更新嵌套数组对象字段的问题的出现原因和解决方法。
Cloud Firestore:使用点标记法更新嵌套数组对象的字段值
在上述内容中,没有直接的方法来更新嵌套数组对象的字段值,可以通过运行事务来获取最新的数组值,然后使用最终的数组值更新数组。代码如下:
await firestore.runTransaction((transaction) => { const students = firestore .collection("users") .where("registered", "==", "yes"); students.forEach((student) => { const firebaseDoc = firestore.doc(student.ref.path); transaction.set( firebaseDoc, { "studentInfo.0.studentId": "345", "studentInfo.0.course.0.courseId": "555", }, { merge: true } ); }); });
在事务中,首先获取数组,然后根据需要更新每个值。这样可以使整个操作具有原子性,从而避免文章中提到的问题。
另外,您还可以将您的Firestore数据库建模如下:
{
"schoolId": "school123",
"studentInfo": {
"studentI23": {
"studentId": "studentI23",
"regDate": "2020-04-18",
"course": [
{
"courseId": "cs123",
"regDate": "2020-05-28",
"status": "COMPLETED"
}
]
}
},
"registered": "yes"
}
在上述示例中,我将数组更改为映射,因为在映射中,您可以根据点标记字段(参考文档)更新每个字段,从而实现所需的结果。这种解决方案将避免任何事务查询并且速度更快。