我正在尝试对 Firestore 集合按模式执行过滤。例如,在我的 Firestore 数据库中,我有一个名为 adidas
的品牌。用户将有一个搜索输入,其中输入“adi”、“adid”、“adida”或“adidas”会返回 adidas
文档。我指出了几种解决方案:
1.获取所有文档并进行前端过滤
var brands = db.collection("brands");
filteredBrands = brands.filter((br) => br.name.includes("pattern"));
由于 Firestore 定价,该解决方案显然不是一个选择。此外,如果文档数量较多,执行请求的时间可能会很长。
2. Elasticsearch的使用或Algolia
这可能很有趣。然而,我认为仅添加这些解决方案对模式搜索的支持有点矫枉过正,而且这很快就会变得昂贵。
3. 创建对象时自定义 searchName
字段
所以我有这个解决方案:在创建文档时,创建一个包含一系列可能的搜索模式的字段:
{
...
"name":"adidas",
"searchNames":[
"adi",
"adida",
"adidas"
],
...
}
以便可以通过以下方式访问该文档:
filteredBrands = db.collection("brands").where("searchNames", "array-contains", "pattern");
所以我有几个问题:
- 您认为第三种解决方案的针对性和效率如何?您认为这比使用 Elasticsearch 或 Algolia 等第三方解决方案好多少?
- 对于对 Firestore 集合执行模式过滤,您还有其他想法吗?
最佳答案
恕我直言,第一个解决方案绝对不是一个选择。下载整个集合来搜索客户端字段根本不切实际,而且成本也非常高。
考虑到可以帮助您在整个 Cloud Firestore 数据库中启用全文搜索,第二个选项是最佳选择。由您决定是否值得使用它。
What do you think about the pertinence and the efficiency of this 3rd solution?
关于第三种解决方案,它可能有效,但它意味着即使品牌名称很长,您也需要创建一系列可能的搜索模式。正如我在您的架构中看到的,您正在添加从第三个字母开始的可能搜索模式,这意味着如果有人搜索 ad
,将找不到结果。此解决方案的缺点是,如果您有一个名为 Asics Tiger
的品牌,并且用户正在搜索 Tig
或 Tige
,那么您最终还是没有结果。
Do you have any other ideas for performing pattern filters over a Firestore collection?
如果您有兴趣仅从单个单词获取结果并使用品牌的起始字母作为模式,我向您推荐一个更好的解决方案,即使用如下所示的查询:
var brands = db.collection("brands");
brands.orderBy("name").startAt(searchName).endAt(searchName + "\uf8ff")
在这种情况下,像 a
或 ad
这样的搜索将完美地工作。除此之外,不需要创建任何其他数组。所以文档编写就会少一些。
我还写了一篇文章,名为:
这也可能有帮助。
关于firebase - 在 Cloud Firestore 集合中按模式搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52627194/