在Cloud Firestore集合上按模式搜索

时间:2018-10-03 12:36:24

标签: firebase google-cloud-firestore

我正在尝试在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集合上执行模式过滤吗?

1 个答案:

答案 0 :(得分:4)

恕我直言,第一个解决方案肯定是不是一个选项。下载整个集合以在客户端搜索字段根本不切实际,而且成本也很高。

考虑到可以帮助您在整个Cloud Firestore数据库中启用全文搜索的事实,第二个选项是最佳选择。由您决定是否值得使用。

  

您如何看待第三种解决方案的针对性和效率?

关于第三个解决方案,它可能会起作用,但它意味着即使品牌名称很长,您也会创建一系列可能的搜索样式。正如我在您的架构中看到的那样,您正在从第三个字母开始添加可能的搜索模式,这意味着如果有人在搜索ad,将不会找到结果。该解决方案的缺点是,如果您有一个名为Asics Tiger的品牌,并且用户在搜索TigTige的情况下,最终将再无结果。

  

您还有其他想法可以对Firestore集合执行模式过滤吗?

如果您只想从一个单词中获得结果,并使用品牌的凝视字母作为结果,我建议您使用下面这样的查询,这是一个更好的解决方案:

var brands = db.collection("brands");
brands.orderBy("name").startAt(searchName).endAt(searchName + "\uf8ff")

在这种情况下,像aad这样的搜索将完全正常。除此之外,将不需要创建任何其他数组。这样可以减少文件的写入。