繁体   English   中英

如何将具有动态 ID 的文档保存到 Cloud Firestore 中? 一直在变

[英]How to save a document with a dynamic id into Cloud Firestore? Always changing

我使用 Cloud Firestore 作为我的数据库 这是我网页上的表单代码,用于在我的 Cloud Firestore 集合中创建一个名为“esequiz”的新文档。 那么我如何以这样的方式对其进行编码,使其始终在数据库中的文档数上加 1? 并且还对数据库中的文档数量设置了限制

form.addEventListener('submit', (e) => {
e.preventDefault();
db.collection('esequiz').add({
    question: form.question.value,
    right: form.right.value,
    wrong: form.wrong.value
});
form.question.value = '';
form.right.value = '';
form.wrong.value = '';
});

它目前有效,但会显示为自动生成的 ID。 我如何使它从数字继续下去,就像我当前的文件一样? 当我保存时,我希望它读取当前的最后一个文档 ID,或者简单地计算文档的数量,然后只需 + 1 在此处输入图片说明

Andrei Cusnir 的见解,不支持在 Cloud Firestore 中计算文档。

现在我正在尝试 Andrei 的方法 2,以降序查询文档,然后使用 .limit 仅检索第一个。

更新

form.addEventListener('submit', (e) => {
e.preventDefault();
let query = db.collection('esequiz');
let getvalue = query.orderBy('id', 'desc').limit(1).get();
let newvalue = getvalue + 1;
db.collection('esequiz').doc(newvalue).set({
    question: form.question.value,
    right: form.right.value,
    wrong: form.wrong.value
});
form.question.value = '';
form.right.value = '';
form.wrong.value = '';
});

没有更多的错误,而是下面的代码返回 [object Promise]

让 getvalue = query.orderBy('id', 'desc').limit(1).get();

所以我的表单保存的时候,保存为[object Promise]1,不知道为什么会这样。 有人可以告诉我如何返回文档 id 值而不是 [object Promise]

我想是因为我确实指定了将文档 id 作为值,我该怎么做? 在此处输入图片说明

更新:最终解决方案

使用了 Andrei 的代码,这里是最终有效的代码。 非常感谢安德烈!

let query = db.collection('esequiz');
//let getvalue = query.orderBy('id', 'desc').limit(1).get();
//let newvalue = getvalue + 1;    
query.orderBy('id', 'desc').limit(1).get().then(querySnapshot => {
    querySnapshot.forEach(documentSnapshot => {
        var newID = documentSnapshot.id;
        console.log(`Found document at ${documentSnapshot.ref.path}`);
        console.log(`Document's ID: ${documentSnapshot.id}`);
        var newvalue = parseInt(newID, 10) + 1;
        var ToString = ""+ newvalue;
        db.collection('esequiz').doc(ToString).set({
            id: newvalue,
            question: form.question.value,
            right: form.right.value,
            wrong: form.wrong.value
        });
    });
    });

如果我理解正确,您正在向 Cloud Firestore 添加数据,并且每个新文档的名称都会有一个增量编号。

如果您查询所有文档,然后计算其中有多少文档,那么随着数据库的增加,您最终会读取很多文档。 不要忘记 Cloud Firestore 是按文档读写收费的,因此如果您有 100 个文档,并且您想添加 ID 为 101 的新文档,那么采用先读取所有文档然后计算它们的方法将花费您100 次读取,然后 1 次写入。 下次它将花费您 101 次读取和 1 次写入。 它会随着您的数据库的增加而继续。

我看到的方式来自两种不同的方法:

方法一:

您可以拥有一个包含数据库所有信息以及下一个名称的文档。

例如

The structure of the database:
esequiz:
        0: 
          last_document: 2
        1: 
          question: "What is 3+3?
          right: "6"
          wrong: "0"
        2: 
          question: "What is 2+3?
          right: "5"
          wrong: "0"

所以这个过程将如下:

  1. 阅读文档“/esequiz/0”计为 1 次阅读
  2. 使用 ID 创建新文档: last_document + 1 Counts as 1 WRITE
  3. 更新保存信息的文档: last_document = 3; 计为 1 次写入

这种方法需要对数据库进行 1 次读取和 2 次写入。

方法二:

您只能从数据库加载最后一个文档并获取它的 ID。

例如

The structure of the database (Same as before, but without the additional doc):
esequiz:
        1: 
          question: "What is 3+3?
          right: "6"
          wrong: "0"
        2: 
          question: "What is 2+3?
          right: "5"
          wrong: "0"

所以这个过程将如下:

  1. 使用使用Cloud Firestore文档订购和限制数据中描述的方法阅读最后一个文档。 因此,您可以将direction=firestore.Query.DESCENDINGlimit(1)结合使用,这将为您提供最后一个文档。 计为 1 次阅读
  2. 现在您知道加载的文档的 ID,因此您可以使用 ID 创建新文档:这将使用加载的值并将其增加 1。计为 1 WRITE

这种方法总共需要对数据库进行 1 次读取和 1 次写入。


我希望这些信息对您有所帮助,并能解决您的问题。 目前不支持对 Cloud Firestore 中的文档进行计数。

更新

为了使排序工作,您还必须将 id 作为文档的一个字段包含在内,以便您可以根据它进行排序。 我已经测试了以下示例,它对我有用:

数据库结构:

esequiz:
        1: 
          id: 1
          question: "What is 3+3?
          right: "6"
          wrong: "0"
        2: 
          id:2
          question: "What is 2+3?
          right: "5"
          wrong: "0"

如您所见,ID 设置为与文档的 ID 相同。

现在您可以根据该文件查询所有文件和订单。 同时,您只能从查询中检索最后一个文档:

const {Firestore} = require('@google-cloud/firestore');
const firestore = new Firestore();

async function getLastDocument(){

    let query = firestore.collection('esequiz');

    query.orderBy('id', 'desc').limit(1).get().then(querySnapshot => {
    querySnapshot.forEach(documentSnapshot => {
        console.log(`Found document at ${documentSnapshot.ref.path}`);
        console.log(`Document's ID: ${documentSnapshot.id}`);
    });
    });

}

OUTPUT:
Found document at esequiz/2
Document's ID: 2

然后你可以把这个 ID 加 1 来生成你的新文档的名字!

更新 2

因此,最初的问题是关于“如何使用具有增量 ID 的文档将数据存储在 Cloud Firestore 中”,目前您面临着在项目中设置 Firestore 的问题。 不幸的是,新提出的问题应该在另一篇 Stackoverflow 帖子中讨论,因为它们与文档的增量 ID 逻辑无关,最好为每个问题保留一个问题,以便为正在寻找的成员提供更好的社区支持寻求有关特定问题的解决方案。 因此,我将在本文中尝试帮助您执行一个简单的 Node.js 脚本并解决最初的问题,即使用增量 ID 存储到 Cloud Firestore 文档。 关于如何在您的项目中设置此功能以及如何在您的页面中使用此功能的其他所有内容都应在附加问题中解决,您还需要提供有关您正在使用的框架、项目设置的尽可能多的信息等等。

因此,让我们使用上述逻辑创建一个简单的 app.js:

  1. 由于您已经拥有 Cloud Firestore,这意味着您已经拥有 Google Cloud Platform 项目(Firestore 所依赖的项目)并且已经启用了适当的 API。 否则它不会工作
  2. 本教程中的指南是Cloud Firestore:Node.js 客户端文档。 它将帮助您了解可以与 Firestore Node.js API 一起使用的所有方法。 您可以找到用于添加、阅读、查询文档和更多操作的有用链接。 我将在此步骤的后面发布完整的工作代码。我只是分享了链接,所以您知道在哪里寻找其他功能
  3. 转到Google Cloud Console 仪表板页面。 您应该使用设置了 Firestore 数据库项目的 Google 帐户登录。
  4. 在右上角,您应该会看到 4 个按钮和您的个人资料图片。 第一个按钮是Activate Cloud Shell 这将在页面底部打开一个终端,其中已经安装了 linux 操作系统和 Google Cloud SDK。 在那里,您可以在 GCP 项目中与您的资源进行交互,并在您的项目中使用之前在本地测试您的代码。
  5. 单击该按钮后,您会注意到终端将在页面底部打开。
  6. 为确保您得到正确的身份验证,我们将设置项目并再次验证帐户,即使默认情况下已经完成。 所以先执行$ gcloud auth login
  7. 在提示的问题上输入Y并按 Enter
  8. 单击生成的链接并在提示窗口中验证您的帐户
  9. 将生成的字符串复制回终端并按回车键。 现在,您应该已通过正确的身份验证。
  10. 然后使用以下命令设置包含 Cloud Firestore 数据库的项目: $ gcloud config set project PROJECT_ID 现在您已准备好构建一个简单的 app.js 脚本并执行它。
  11. 创建一个新的 app.js 文件: nano app.js
  12. 在里面粘贴我的代码示例,可以在这个GitHub 链接中找到。 它包含完整的工作示例和许多解释每个部分的注释,因此最好通过 GitHub 链接共享它而不是粘贴在这里。 无需做任何修改,此代码将完全执行您要执行的操作。 我已经自己测试过了,它正在工作。
  13. 执行脚本为: node app.js
  14. 这会给你以下错误:

    错误:找不到模块“@google-cloud/firestore”

由于我们正在导入库@google-cloud/firestore但尚未安装它。

  1. 安装@google-cloud/firestore库如下: $ npm i @google-cloud/firestore DOC 中描述。
  2. 再次执行脚本: $ node app.js
  3. 您应该会看到例如Document with ID: 3 is written.
  4. 如果再次执行,您应该看到例如Document with ID: 4 is written.

所有这些更改也应出现在您的 Cloud Firestore 数据库中。 正如您所看到的,它正在加载最后一个文档的 ID,它正在创建一个新 ID,然后使用给定的参数创建一个新文档,同时使用新生成的 ID 作为文档名称。 这正是最初的问题。

因此,我与您分享了完整的代码,这些代码可以正常工作并且完全符合您的要求。 不幸的是,其他新提出的问题应该在另一个 Stackoverflow 帖子中解决,因为它们与最初的问题无关,即“如何创建具有增量 ID 的文档”。 我建议您按照步骤操作并创建一个工作示例,然后尝试将逻辑实现到您的项目中。 但是,如果您仍然面临如何在项目中设置 Firestore 的任何问题,那么您可以提出另一个问题。 之后,您可以结合这两种解决方案,您将拥有可以运行的应用程序!

祝你好运!

我不认为您尝试获取集合长度的方式是正确的,而且我完全不确定获得该长度的最佳方式是什么。 因为当您尝试读取集合的所有记录时,您尝试实施的方法将花费更多。

但是可以有其他选择来获得您需要的号码。

  1. 开始将 ID 存储在记录中,并使用限制 1 和对 ID 的降序进行查询。
  2. 将最新的数字存储在另一个集合中,并在每次创建新记录时递增该数字,并在需要时获取相同的数字。

如果在没有事务的情况下发出并发请求,这些方法可能会失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM