当我通过API创建新文档时,我想提交(或原子更新)属于根项目文档的统计信息集合:
const increment = firebase.firestore.FieldValue.increment(1)
let aggregation: LooseObject = {
totalProjects: increment,
tags: [],
categories: [],
}
const project = fakeProject() // some debug func to return a dummy project object
const projectRef = db.collection('projects').doc()
const projectStatsRef = db.collection('projects').doc('--stats--')
project.categories.forEach((category: string) => {
aggregation.categories[category] = increment
})
project.tags.forEach((tag: string) => {
aggregation.tags[tag] = increment
})
console.log(aggregation)
const batch = db.batch()
batch.set(projectRef, project)
batch.set(projectStatsRef, aggregation, {
merge: true,
})
batch.commit()
当我检查控制台时,我得到了汇总文档的以下转储(这是我希望在所附的屏幕截图中看到的数据的形状):
{
totalProjects: NumericIncrementTransform { operand: 1 },
tags: [
raid: NumericIncrementTransform { operand: 1 },
'attack-of-the-clone': NumericIncrementTransform { operand: 1 },
'star-wars': NumericIncrementTransform { operand: 1 }
],
categories: [ movie: NumericIncrementTransform { operand: 1 } ]
}
但是,当文档提交到Firestore时,只会显示以下结构(标签和类别数组均为空)
据我了解,merge
应该对所有嵌套对象进行深度合并。如果不是这种情况,我该如何实现自己的追求?
我知道这种类型的存储不能扩展成千上万的标签,我只是第一次修改firestore,想看看我将如何使这种东西工作
答案 0 :(得分:3)
设置合并实际上并不是您期望的“深度”合并。当您传递带有键/值对的对象时,Firestore将使用新数据完全覆盖这些键的每个每个指定的字段,但保留文档中的所有其他字段单独。因此,如果您有一个包含字段{a,b,c}的文档,并且对b进行了合并设置,则b将被完全覆盖,而其他两个将保持不变。
最重要的是,Firestore完全不支持设置嵌入在数组中的特定映射字段值。换句话说,没有使用数组索引的直接数组项更新。
如果必须具有此文档结构,则需要进行事务处理才能读取文档,修改内存中的数组字段以显示所需的格式,然后将该字段写回到文档中。是的,这很不方便,但这是涉及数组项更新的唯一方法。