Firebase 当某些文档可能';你被删除了吗?
假设我有一个这样的结构:Firebase 当某些文档可能';你被删除了吗?,firebase,google-cloud-firestore,Firebase,Google Cloud Firestore,假设我有一个这样的结构: items: { id1: { likes: 123 }, id2: { likes: 456 }, id3: { sourceId: 'id1', likes: 123 }, id4: { sourceId: 'id1', likes: 123 } [,...] } 其中,任何项都可以是源项或引用源项的项。引用源项的目的是使共享相同sourceId的所有项的计数器保持一致 因此,当我
items: {
id1: {
likes: 123
},
id2: {
likes: 456
},
id3: {
sourceId: 'id1',
likes: 123
},
id4: {
sourceId: 'id1',
likes: 123
}
[,...]
}
其中,任何项都可以是源项或引用源项的项。引用源项的目的是使共享相同sourceId的所有项的计数器保持一致
因此,当我更改源项上的计数器时,我希望将该计数器的值批量写入所有将该项作为其源ID的项
我关心的
假设我读入引用某个sourceId的文档,然后我将一批更改提交给所有文档。如果批处理中的一小部分文档在读入文档后的一小段时间内被删除,或者发生罕见但可能的写入速率冲突,该怎么办?是否因为1或2个文档未能更新而没有更新任何计数器
是否可以提交一批独立地将更改写入其每个文档,这样,如果其中一个文档失败,则不会影响其他文档的写入
或者,对于这种情况,最好读入引用某个sourceId的文档,然后并行地将更改写入每个文档,以实现写独立性。我不喜欢这种方法,因为请求的数量将是批处理的大小
您的想法是什么?仔细阅读API文档。它会回答你的问题。由于您没有显示批处理代码(是否使用set?update?),因此我们必须查看API文档以评估故障情况: 创建() 如果该位置存在文档,则该批处理将失败 听起来您可能没有使用create(),但这是一个失败案例 集合() 如果文档尚不存在,将创建该文档 因此,如果在提交批之前删除了记录的数据集,则该集不会失败 更新() 如果文档尚不存在,则更新将失败,整个过程将失败 该批产品将被拒收 因此,如果尝试更新不存在的文档,批处理将失败
如果您想根据文档的存在和内容决定如何处理每个文档,然后控制失败案例,请使用。如果我理解您的问题,我有一个类似的场景,下面是我如何处理的。首先,我将生成的通用ID(uid)用于我的所有项目键/ID。然后,您要做的是在孙子上,只需编写与之关联的父级的uid。每个孙子孙女可以与多个父孙女关联 创建新项时,必须使用项的uid递归更新父项,以便父项具有其所有关联子项的记录
fetchPromise = [];
fetchArray = [];
if(!selectIsEmpty("order-panel-one-series-select") || !selectIsUnselected(orderPanelOneSeriesSelect)){
orderPanelOneTitle.innerHTML = "Select " + orderPanelOneSeriesSelect.value.toString().toUpperCase() + " Option";
}
//on change we need to populate option select based on this value
//now we need to get the particular series doc and fill get array then prmise all to get all options
familyuid = getRecordFromList(doc.getElementById("order-panel-one-family-select"),orderPanelOneFamilySelect.selectedIndex);
seriesuid = getRecordFromList(doc.getElementById("order-panel-one-series-select"),orderPanelOneSeriesSelect.selectedIndex);
optionuid = getRecordFromList(doc.getElementById("order-panel-one-option-select"),orderPanelOneOptionsSelect.selectedIndex);
optionRef = db.collection("products").doc(familyuid).collection("option");
itemRef = db.collection("products").doc(familyuid).collection("item");
targetRef = db.collection("products").doc(familyuid).collection("option").doc(optionuid);
try {
targetRef.get().then(function(snap) {
if (snap.exists) {
for (var key in snap.data()) {
if (snap.data().hasOwnProperty(key)) {
fetchPromise = itemRef.doc(key).get();
fetchArray.push(fetchPromise);
}
}
Promise.all(fetchArray).then(function(values) {
populateSelectFromQueryValues(values,"order-panel-one-item-select");
if(!selectIsEmpty("order-panel-one-item-select")){
enableSelect("order-panel-one-item-select");
}
targetRef.get().then(function(snap){
if(snap.data().name){
var str = snap.data().name.toString();
orderAsideInfo.innerHTML = "Select " + capitalizeFirstLetter(str) + " item.";
}
});
});
}
}).catch(function(error) {
toast("error check console");
console.log("Error getting document:", error);
});
}
我指的是更新;然而,对于我的用例来说,这似乎是危险的。如果500份文档中有1份被删除,则所有500份文档都会失败。我不知道如何对多个文档进行事务处理,因此我将坚持并行更新文档。我提供的事务文档链接应该会有所帮助。您只需获取()多个文档,然后根据需要对其进行更改。我不确定DOM代码在做什么,但我理解您的建议。你的建议似乎做得太多了。例如,建议将子id写入父id。但这并不能解决问题。在批提交/完成之间,子文档仍可能被删除。您是否查看了?换句话说,在服务器端执行此操作。当一个字段值更改时,根据这个新值更新另一个值。是的,我打算为此使用触发器。