如何将具有动态 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 = '';
});
没有更多错误,而是下面的代码 returns [object Promise]
let getvalue = query.orderBy('id', 'desc').limit(1).get();
所以当我的表格保存时,它保存为[object Promise]1,我不知道为什么会这样。有人可以建议我如何 return 文档 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
});
});
});
我认为您尝试获取集合长度的方法不正确,而且我也完全不确定获取该集合长度的最佳方法是什么。因为当您尝试读取集合的所有记录时,您尝试实现的方法会花费更多。
但是可以通过其他方式获得您需要的号码。
- 开始将 ID 存储在记录中,并以限制 1 和 ID 降序进行查询。
- 将最新的数字存储在另一个集合中,并在每次创建新记录时递增,并在需要时获取相同的数字。
如果在没有事务的情况下发出并发请求,这些方法可能会失败。
如果我理解正确的话,您正在向 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"
所以流程如下:
- 阅读文档“/esequiz/0”计为 1 READ
- 使用 ID 创建新文档:
last_document + 1
计为 1 WRITE
- 更新包含信息的文档:
last_document = 3;
计为 1 WRITE
这种方法需要您对数据库进行 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"
所以流程如下:
- 使用 Order and limit data with Cloud Firestore 文档中描述的方法阅读最后一篇文档。因此,您可以将
direction=firestore.Query.DESCENDING
与 limit(1)
组合使用,这将为您提供最后一个文档。 计为 1 次阅读
- 现在您知道加载文档的 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
所以,最初的问题是关于 "How to store data in the Cloud Firestore with documents having incremental ID",目前您正面临为您的项目设置 Firestore 的问题。不幸的是,新提出的问题应该在另一个 Whosebug post 中进行讨论,因为它们与文档的增量 ID 逻辑无关,最好每个问题保留一个问题,以提供更好的社区支持正在寻找有关特定问题的解决方案的成员。因此,在此 post 中,我将尝试帮助您执行一个简单的 Node.js 脚本并解决初始问题,即使用增量 ID 存储到 Cloud Firestore 文档。其他一切,关于如何在你的项目中设置这个以及如何在你的页面中使用这个功能,应该在附加问题中解决,你还需要提供尽可能多的关于你正在使用的框架的信息,项目设置等等
那么,让我们用上述逻辑做一个简单的 app.js 工作:
- 由于您的 Cloud Firestore 已经在运行,这意味着您已经拥有 Google Cloud Platform 项目(Firestore 所依赖的项目)并且已经启用了适当的 API。 否则无法运行.
- 本教程中的指南是 Cloud Firestore: Node.js Client 文档。它将帮助您了解可用于 Firestore Node.js API 的所有方法。您可以找到对添加、阅读、查询文档和更多操作有用的 links。 (我将 post 稍后在此步骤中的整个工作代码。我刚刚分享了 link 这样您就知道在哪里寻找其他功能)
- 转到 Google Cloud Console Dashboard 页面。您应该使用您的 Google 帐户登录,其中设置了带有 Firestore 数据库的项目。
- 在右上角,您应该会看到 4 个按钮和您的头像。第一个按钮是 激活云 Shell。这将在页面底部打开一个终端,其中 linux OS 和 Google Cloud SDK 已经安装。您可以在那里与 GCP 项目中的资源进行交互,并在本地测试您的代码,然后再将其用于您的项目。
- 单击该按钮后,您会注意到终端将在页面底部打开。
- 为确保您得到正确的身份验证,我们将设置项目并再次验证帐户,即使默认情况下已经完成。所以先执行
$ gcloud auth login
- 在提示的问题中键入
Y
并按回车键
- 点击生成的link,在提示的window
上验证你的账号
- 将生成的字符串复制回终端并按回车键。现在您应该已通过正确的身份验证。
- 然后使用以下命令设置包含 Cloud Firestore 数据库的项目:
$ gcloud config set project PROJECT_ID
。现在您已准备好构建一个简单的 app.js 脚本并执行它。
- 创建一个新的 app.js 文件:
nano app.js
- 在里面粘贴我的代码示例,可以在这个 GitHub link 中找到。它包含完整的示例和许多解释每个部分的注释,因此最好通过 GitHub link 共享它而不是粘贴在这里。在不做任何修改的情况下,此代码将执行您正在尝试执行的操作。我已经亲自测试过它并且可以正常工作。
- 执行脚本为:
node app.js
- 这会给你以下错误:
Error: Cannot find module '@google-cloud/firestore'
因为我们正在导入库 @google-cloud/firestore
但还没有安装它。
- 安装
@google-cloud/firestore
库如下:$ npm i @google-cloud/firestore
。在 DOC. 中描述
- 再次执行脚本:
$ node app.js
。
- 你应该看到例如
Document with ID: 3 is written.
- 如果你再次执行,你应该看到例如
Document with ID: 4 is written.
所有这些更改也应该出现在您的 Cloud Firestore 数据库中。如您所见,它正在加载上一个文档的 ID,它正在创建一个新 ID,然后使用给定的参数创建一个新文档,同时使用新生成的 ID 作为文档名称。这正是最初的问题所在。
因此,我已经与您分享了完整的代码,该代码可以正常工作并且完全符合您的要求。不幸的是,其他新提出的问题应该在另一个 Whosebug post 中解决,因为它们与初始问题 "How to create documents with incremental ID" 无关。我建议您遵循这些步骤并有一个工作示例,然后尝试将逻辑实施到您的项目中。但是,如果您仍然面临如何在项目中设置 Firestore 的任何问题,那么您可以提出另一个问题。之后,您可以将这两种解决方案结合起来,您将拥有可用的应用程序!
祝你好运!
我正在使用 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 = '';
});
没有更多错误,而是下面的代码 returns [object Promise]
let getvalue = query.orderBy('id', 'desc').limit(1).get();
所以当我的表格保存时,它保存为[object Promise]1,我不知道为什么会这样。有人可以建议我如何 return 文档 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
});
});
});
我认为您尝试获取集合长度的方法不正确,而且我也完全不确定获取该集合长度的最佳方法是什么。因为当您尝试读取集合的所有记录时,您尝试实现的方法会花费更多。
但是可以通过其他方式获得您需要的号码。
- 开始将 ID 存储在记录中,并以限制 1 和 ID 降序进行查询。
- 将最新的数字存储在另一个集合中,并在每次创建新记录时递增,并在需要时获取相同的数字。
如果在没有事务的情况下发出并发请求,这些方法可能会失败。
如果我理解正确的话,您正在向 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"
所以流程如下:
- 阅读文档“/esequiz/0”计为 1 READ
- 使用 ID 创建新文档:
last_document + 1
计为 1 WRITE - 更新包含信息的文档:
last_document = 3;
计为 1 WRITE
这种方法需要您对数据库进行 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"
所以流程如下:
- 使用 Order and limit data with Cloud Firestore 文档中描述的方法阅读最后一篇文档。因此,您可以将
direction=firestore.Query.DESCENDING
与limit(1)
组合使用,这将为您提供最后一个文档。 计为 1 次阅读 - 现在您知道加载文档的 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
所以,最初的问题是关于 "How to store data in the Cloud Firestore with documents having incremental ID",目前您正面临为您的项目设置 Firestore 的问题。不幸的是,新提出的问题应该在另一个 Whosebug post 中进行讨论,因为它们与文档的增量 ID 逻辑无关,最好每个问题保留一个问题,以提供更好的社区支持正在寻找有关特定问题的解决方案的成员。因此,在此 post 中,我将尝试帮助您执行一个简单的 Node.js 脚本并解决初始问题,即使用增量 ID 存储到 Cloud Firestore 文档。其他一切,关于如何在你的项目中设置这个以及如何在你的页面中使用这个功能,应该在附加问题中解决,你还需要提供尽可能多的关于你正在使用的框架的信息,项目设置等等
那么,让我们用上述逻辑做一个简单的 app.js 工作:
- 由于您的 Cloud Firestore 已经在运行,这意味着您已经拥有 Google Cloud Platform 项目(Firestore 所依赖的项目)并且已经启用了适当的 API。 否则无法运行.
- 本教程中的指南是 Cloud Firestore: Node.js Client 文档。它将帮助您了解可用于 Firestore Node.js API 的所有方法。您可以找到对添加、阅读、查询文档和更多操作有用的 links。 (我将 post 稍后在此步骤中的整个工作代码。我刚刚分享了 link 这样您就知道在哪里寻找其他功能)
- 转到 Google Cloud Console Dashboard 页面。您应该使用您的 Google 帐户登录,其中设置了带有 Firestore 数据库的项目。
- 在右上角,您应该会看到 4 个按钮和您的头像。第一个按钮是 激活云 Shell。这将在页面底部打开一个终端,其中 linux OS 和 Google Cloud SDK 已经安装。您可以在那里与 GCP 项目中的资源进行交互,并在本地测试您的代码,然后再将其用于您的项目。
- 单击该按钮后,您会注意到终端将在页面底部打开。
- 为确保您得到正确的身份验证,我们将设置项目并再次验证帐户,即使默认情况下已经完成。所以先执行
$ gcloud auth login
- 在提示的问题中键入
Y
并按回车键 - 点击生成的link,在提示的window 上验证你的账号
- 将生成的字符串复制回终端并按回车键。现在您应该已通过正确的身份验证。
- 然后使用以下命令设置包含 Cloud Firestore 数据库的项目:
$ gcloud config set project PROJECT_ID
。现在您已准备好构建一个简单的 app.js 脚本并执行它。 - 创建一个新的 app.js 文件:
nano app.js
- 在里面粘贴我的代码示例,可以在这个 GitHub link 中找到。它包含完整的示例和许多解释每个部分的注释,因此最好通过 GitHub link 共享它而不是粘贴在这里。在不做任何修改的情况下,此代码将执行您正在尝试执行的操作。我已经亲自测试过它并且可以正常工作。
- 执行脚本为:
node app.js
- 这会给你以下错误:
Error: Cannot find module '@google-cloud/firestore'
因为我们正在导入库 @google-cloud/firestore
但还没有安装它。
- 安装
@google-cloud/firestore
库如下:$ npm i @google-cloud/firestore
。在 DOC. 中描述
- 再次执行脚本:
$ node app.js
。 - 你应该看到例如
Document with ID: 3 is written.
- 如果你再次执行,你应该看到例如
Document with ID: 4 is written.
所有这些更改也应该出现在您的 Cloud Firestore 数据库中。如您所见,它正在加载上一个文档的 ID,它正在创建一个新 ID,然后使用给定的参数创建一个新文档,同时使用新生成的 ID 作为文档名称。这正是最初的问题所在。
因此,我已经与您分享了完整的代码,该代码可以正常工作并且完全符合您的要求。不幸的是,其他新提出的问题应该在另一个 Whosebug post 中解决,因为它们与初始问题 "How to create documents with incremental ID" 无关。我建议您遵循这些步骤并有一个工作示例,然后尝试将逻辑实施到您的项目中。但是,如果您仍然面临如何在项目中设置 Firestore 的任何问题,那么您可以提出另一个问题。之后,您可以将这两种解决方案结合起来,您将拥有可用的应用程序!
祝你好运!