【发布时间】:2021-05-31 20:55:26
【问题描述】:
我正在为这个项目使用 Firebase Firestore,我正在尝试实现数据加载器以减少对服务器的请求。
在这种特殊情况下,我有一个结构如下的 Category 集合: (我将使用 typescript 来更好地定义我的代码)
type Category = {
name: String
parent?: Category
}
当我查询 graphql 端点时,我会在解析器中验证该类别是否有父类,如果存在,我会查询数据库以获取详细信息。数据加载器来了。
这是我的 Firestore 的 Dataloader 实现:
private dataLoader = new DataLoader(async (ids: readonly string[]) => {
// firestore limits batches to 10
let batches: Category[] = [];
const tmp = [...ids];
while (tmp.length) {
const batch = tmp.splice(0, 10);
const result = await this.collection.where(FieldPath.documentId(), 'in', [...batch]).get();
batches = [...batches, ...result.docs.map(d => ({ id: d.id, ...d.data() } as Category))];
}
return batches;
});
解析器本身调用此方法
public async getById(id: string): Promise<Category> {
const foo = await this.dataLoader.load(id);
console.log('required', id, 'received', foo.id);
return foo;
}
但正如您在此示例输出中看到的那样,它搞砸了很多时间:
required ztdOcVv9JdNp6U54ySed received 4jXbScd1qTwPStXocaoc
required Qnb86GsOy0gSgGxmMqYR received NeuCCRrJyurQTxvlAVhs
required NeuCCRrJyurQTxvlAVhs received Qnb86GsOy0gSgGxmMqYR
required 4jXbScd1qTwPStXocaoc received ztdOcVv9JdNp6U54ySed
我的理解是某个地方的异步会导致一些麻烦,但不知道在哪里或如何解决这个问题。这就是我在这里寻求帮助的原因。
提前致谢
【问题讨论】:
-
这些看起来像是从 Firestore 自动生成的 ID 字符串。当您将新文档添加到集合中时,Firestore 会自动生成文档标识符。签入 Firebase Firestore 控制台进行检查。
-
@Andrew 感谢您的评论并对延误表示抱歉。它们实际上是自动生成的 ID。它们存在于数据库中。只是不是我需要的。它们不匹配,我不明白这个输出是如何生成的。完全没有意义
-
您可以在您的问题中添加数据库结构的副本吗?你希望看到什么?你提到它搞砸了,但我不确定你的描述是怎么回事。
-
Andrew,正如您可以从类型代码中推断的那样,只是一个字段、名称和一个称为 parent 的可选字段,当存在时,它是对同一集合中另一个类别的文档引用。在数据加载器中,我传递了一批 id(十个一组,因为 Firebase 本身的限制),它应该返回相关项目。 Instedad,它返回“洗牌结果”,正如您在示例输出中看到的那样。
-
好吧,通读这篇文章,我想指出您没有订购结果,您正在查看批次中包含的任何结果......所以真的是订单你得到的不是“洗牌”,而是它在 Firestore 中保存的顺序。其中,查看第一个字符是按字母顺序排列的,这意味着它按字符值排序 (4
标签: typescript firebase google-cloud-firestore graphql graphql-js