【问题标题】:Write Firebase Batch Function to Delete data in an array编写 Firebase 批处理函数以删除数组中的数据
【发布时间】:2020-11-20 03:22:08
【问题描述】:

我已经实现了以下一个使用批处理删除数据的功能。但它给了我一个未处理的异常,说“无法修改已提交的 WriteBatch。我认为这是因为我正在使用 for 循环。

data.forEach(async (element: any) => {
 const snapshot = await db
  .collection("car")
  .doc(element.brand)
  .collection("model")
  .doc(element.model)
  .collection("year")
  .orderBy("year")
  .get();

snapshot.forEach(async (doc) => {

  if (element.service === "Car Spa") {
    console.log("Cond1")
    const ref1 = db
      .collection(element.service)
      .doc(element.sub_service)
      .collection("Body Type")
      .doc(element.bodyType)
      .collection("model")
      .doc(element.model)
      .collection("mechanic")
      .doc("email@gmail.com")
    batch.delete(ref1);
    operationCounter++;
  } else {
    console.log("Cond:2")
    const ref2 = db
      .collection(element.service)
      .doc(element.sub_service)
      .collection("vehicle")
      .doc(element.brand)
      .collection("model")
      .doc(element.model)
      .collection("year")
      .doc(doc.data().year.toString())
      .collection("mechanic")
      .doc("email@gmail.com")
    batch.delete(ref2)
    operationCounter++;
  }

  let _id =
    element.service +
    element.sub_service +
    element.brand +
    element.model +
    doc.id;

  const ref3 = db
    .collection("mechanics")
    .doc("email@gmail.com")
    .collection("services")
    .doc(_id)
  batch.delete(ref3);
  operationCounter++;

  if (operationCounter === 500) {
    console.log("MORE THAN 500");
    batches.push(batch.commit());
    batch = db.batch();
    operationCounter = 0;
  }
});
});
if (batches.length === 0) {
await batch.commit().then(() => console.log("DONE ONE BAtch"));
} else {
await Promise.all(batches).then(() => console.log("DONE"));
}

请提出一种有效地在循环内进行批量删除的方法。 提前致谢!

【问题讨论】:

  • 您的错误可能在这里operationCounter === 500。这不应该是operationCounter >= 500 吗?另外,您能否发布一个自包含的代码,以便我可以尝试重现您的问题,因为我真的无法围绕您的数据模型:)?
  • 通常即使操作员计数器小于 500,它也会给出上述异常。当我查看日志时,我发现该函数在执行 data.foreach 之前跳到了末尾。同样在 snapshot.foreach 中也有同样的问题。你能建议我解决这个问题吗?我尝试了 for 循环,对于一些数据量来说删除是可以的。对于一个巨大的计数,它可能会崩溃

标签: javascript firebase google-cloud-firestore


【解决方案1】:

没有看到您的所有代码,很难确切地知道它是如何失败的或如何使其高效。我已经编辑了你的代码,这应该可以工作: 问题在于 foreach 看到这个问题,Using async/await with a forEach loop

这是正确的 forEach 循环

let batch = db.firestore().batch()

for (const element of data.docs) {
  const snapshot = await db
  .collection("car")
  .doc(element.brand)
  .collection("model")
  .doc(element.model)
  .collection("year")
  .orderBy("year")
  .get();

for( const doc of snapshot.docs) {

    if (element.service === "Car Spa") {
      
      const ref1 = db
        .collection(element.service)
        .doc(element.sub_service)
        .collection("Body Type")
        .doc(element.bodyType)
        .collection("model")
        .doc(element.model)
        .collection("mechanic")
        .doc("email@gmail.com")
      
        batch.delete(ref1);
     
        operationCounter++;
    } else {
     
      const ref2 = db
        .collection(element.service)
        .doc(element.sub_service)
        .collection("vehicle")
        .doc(element.brand)
        .collection("model")
        .doc(element.model)
        .collection("year")
        .doc(doc.data().year.toString())
        .collection("mechanic")
        .doc("email@gmail.com")
      batch.delete(ref2)
      operationCounter++;
    }

  let _id =
    element.service +
    element.sub_service +
    element.brand +
    element.model +
    doc.id;

  const ref3 = db
    .collection("mechanics")
    .doc("email@gmail.com")
    .collection("services")
    .doc(_id)
  batch.delete(ref3);
  operationCounter++;

  if (operationCounter === 500) {
    
    await batch.commit();
    batch = db.batch();
    operationCounter = 0;
  }
}
}

if (batch.length === 0) {
  await batch.commit().then(() => console.log("DONE LAST BATCH"));
}

【讨论】:

  • 你的代码是我实现的。但是 data.foreach 和 snapshot.foreach 没有按预期工作。 Foreach 循环不像 for 循环那样执行。有时它会跳过一些循环。所以我得到一个“未处理的错误”
  • 抱歉,等待在 forEach 中没有按预期工作。如果您使用 for of 循环,则 await 将按预期工作。请参阅我编辑的帖子。查看这篇文章stackoverflow.com/questions/37576685/…
  • 非常感谢 :)
  • 仍然 foreach 给出错误。 for-loop 执行良好,但会因大量数据而崩溃。我从您在 foreach 循环中提供的链接中得到了一个想法。谢谢你
  • 嗯。但不适用于大量数据(超过 150 条记录)
猜你喜欢
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
  • 1970-01-01
  • 2017-12-04
  • 1970-01-01
相关资源
最近更新 更多