【发布时间】:2021-05-18 07:49:38
【问题描述】:
我正在开发一个带有 Firestore 数据库的 React 电子商务应用程序,其中客户应该能够过滤多种颜色(使用 OR 逻辑)和多种样式(使用 OR 逻辑)和多个品牌(使用 OR 逻辑)等,并且检索与这些过滤器匹配的前 50 个产品。
这里的主要限制是尽管使用.where("category", "==", "T-Shirts").where("color", "==", "Red") 链接多个等式是可能的,但firestore 查询(客户端或服务器)确实只允许单个“in”类型的查询。这意味着,如果用户想要查看 A 和 B 品牌的黑色或红色产品,则无法进行像 .where('color', 'in', ['Red', 'Black']).where('brand', 'in', ['A', 'B']) 这样的查询。请参阅https://firebase.google.com/docs/firestore/query-data/queries#query_limitations 和https://firebase.google.com/docs/firestore/query-data/queries#limitations_2 了解更多详情。
为了克服这个 Firestore 文档,建议使用两个不同的查询并在客户端处理数据。但是,在这种用例中没有提到分页,这意味着;
如果产品集合中有 1000 个文档,首先您必须以 .where('color', 'in', ['Red', 'Black']) 运行查询以获取结果,假设是 400 个文档,然后运行另一个查询 resultsOfFirstQuery.where('brand', 'in', ['A', 'B']).limit(50);,这将获取前 50 个文档,如果确实有50多个。
虽然这种方法看起来很简单,但实际上它会读取 400 个文档以便只显示其中的 50 个。如果用户更改单个过滤器字段,则这种类型的阅读会一次又一次地重复。为了克服这个问题,我已经想到了可能的解决方案;
-
获取与单个选择过滤器匹配的所有产品,例如类别(在我的情况下,客户只能设置一个类别字段)。并在客户端进行所有过滤。使用这种方法,应用程序仍会读取大量文档,但至少会在会话期间重复使用这些文档。
-
在服务器环境中运行多个查询,例如使用 Node.js 的云存储功能,并仅获取与所有过滤器匹配的前 50 个文档。使用这种方法,客户端只接收到想要的数据而不是更多,但服务器仍然读取很多。
-
限制每一步的查询,如果没有产品,用查询游标重新运行相同的查询。例如。
.where('color', 'in', ['Red', 'Black']).limit(50).startAfter(firstDoc)并运行resultsOfFirstQuery.where('brand', 'in', ['A', 'B']),如果有 5 个产品,则使用startAfter(lastDocLastQuery)重新运行查询,直到超过 50 个为止。使用这种方法,您仍然会阅读大量文档,但最终会逐渐将阅读次数从 50 增加到 50,直到您有 50 个产品匹配。 -
借助云功能在 Firebase 中创建自动化文档,例如
Colors: {red:[product1ID,product2ID....], ....}并根据过滤器在服务器端使用云功能获取相应的文档,创建匹配数组的叉积(AND 逻辑)并将其前 50 个元素推送到客户端。知道哪些产品要显示客户端然后处理获取客户端库。
这里还有其他我想念的方法吗?考虑到文档读取和客户端数据以及电池使用情况,您认为哪种方法是最好的方法?
我知道我的问题可以称为基于意见的问题,但这确实是个问题,我不想在每次出现导航时都获取数百个产品数据,即使在同一个会话中也是如此。我需要一种结合过滤、分页、存储本地数据的有效方法,但找不到适合上述问题范围的方法。
【问题讨论】:
-
尽量将问题限制在一个主题上。在问题中添加多个问题将稀释答案并使它们成为文本墙。发布多个问题是您最好的选择。
-
我将重新格式化内容并将反应位作为一个不同的问题发布,再次感谢您的审核。
-
这取决于你的数据结构,这个问题更适合DBA exchange
标签: firebase google-cloud-firestore google-cloud-functions