Vue.js与Firebase:如何修改查询语句以更新指定项目的sections数组
更新Firestore中嵌套的项目sections数组
看起来你现在的需求是找到特定field下的某个项目,然后更新它的sections数组——不管是添加新的section,还是修改已有section的内容对吧?之前用arrayUnion的方式是把整个项目元素添加到projects数组里,这显然不是你要的效果,因为你要操作的是已有项目里的嵌套数组。
Firestore没有直接修改嵌套数组中元素的API,所以我们得先把整个文档数据取出来,找到目标项目修改它的sections,再把整个projects数组更新回去。下面是具体的修改方案:
场景1:添加新Section到指定Project
假设你已经知道要修改的project_id,并且有一个新的newSection对象要添加到这个项目的sections里,代码可以这么写:
const database = db.collection('fields'); const targetFieldId = this.$route.params.field_id; const targetProjectId = this.targetProjectId; // 从Vue数据中获取要修改的项目ID const newSection = { section_id: 'new-section-id', section_name: '新功能模块', section_info: '模块详细描述', contract_value: 0, approved_30_6_20: 0, approved_20_21: 0, total_approved_2021: 0, companies: [] }; database.where('field_id', '==', targetFieldId).get() .then(querySnapshot => { querySnapshot.forEach(doc => { // 取出当前文档的projects数组,为空则初始化空数组 const currentProjects = doc.data().projects || []; // 遍历项目,找到目标项目并更新sections const updatedProjects = currentProjects.map(project => { if (project.project_id === targetProjectId) { // 给目标项目的sections添加新元素(手动去重的话可以先判断section_id是否存在) const isSectionExists = project.sections.some(s => s.section_id === newSection.section_id); const updatedSections = isSectionExists ? project.sections : [...project.sections, newSection]; return { ...project, sections: updatedSections }; } // 其他项目保持原样 return project; }); // 将修改后的projects数组更新回文档 return database.doc(doc.id).update({ projects: updatedProjects }); }); }) .then(() => { this.$router.push('/'); }) .catch(err => { console.error('更新sections失败:', err); });
场景2:修改已有Section的内容
如果是要更新某个已有section的字段(比如修改contract_value或execution_rate),只需要在找到目标项目后,再定位到具体section进行修改:
// ...前面的变量定义和获取文档的代码和场景1一致 const targetSectionId = this.targetSectionId; // 要修改的section的ID const updatedContractValue = 150000; // 新的合同金额 database.where('field_id', '==', targetFieldId).get() .then(querySnapshot => { querySnapshot.forEach(doc => { const currentProjects = doc.data().projects || []; const updatedProjects = currentProjects.map(project => { if (project.project_id === targetProjectId) { // 找到目标section并更新字段 const updatedSections = project.sections.map(section => { if (section.section_id === targetSectionId) { return { ...section, contract_value: updatedContractValue }; } return section; }); return { ...project, sections: updatedSections }; } return project; }); return database.doc(doc.id).update({ projects: updatedProjects }); }); }) .then(() => { this.$router.push('/'); }) .catch(err => { console.error('更新section字段失败:', err); });
关键注意点
- Firestore不支持直接操作嵌套数组内的元素,必须先获取整个数组修改后再整体更新。
- 如果你的
projects数组规模很大,这种方式可能存在性能损耗,但对于常规业务场景完全够用。 - 若要处理多用户并发修改的场景,可以使用Firestore的事务来确保数据一致性。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

