【问题标题】:Search by pattern on Cloud Firestore collection在 Cloud Firestore 集合上按模式搜索
【发布时间】:2019-03-08 16:38:17
【问题描述】:

我正在尝试按模式对 Firestore 集合执行过滤。例如,在我的 Firestore 数据库中,我有一个名为 adidas 的品牌。用户将有一个搜索输入,其中键入“adi”、“adid”、“adida”或“adidas”会返回adidas 文档。我指出了几个解决方案:


1.获取所有文档并进行前端过滤

var brands = db.collection("brands");
filteredBrands = brands.filter((br) => br.name.includes("pattern"));

由于 Firestore 的定价,这个解决方案显然不是一个选项。此外,如果文档数量很多,执行请求可能会很长。


2.ElasticsearchAlgolia的使用

这可能很有趣。但是,我认为将这些解决方案仅添加对模式搜索的支持有点矫枉过正,而且这很快就会变得昂贵。


3. 创建对象时自定义searchName字段

所以我有这个解决方案:在创建文档时,创建一个包含一系列可能搜索模式的字段:

{
    ...
    "name":"adidas",
    "searchNames":[
        "adi",
        "adida",
        "adidas"
    ],
    ...
}

以便可以通过以下方式访问文档:

filteredBrands = db.collection("brands").where("searchNames", "array-contains", "pattern");

所以我有几个问题:

  • 您如何看待第三种解决方案的针对性和效率?您认为这比使用第三方解决方案(如 Elasticsearch 或 Algolia)要好多少?
  • 您对在 Firestore 集合上执行模式过滤器有任何其他想法吗?

【问题讨论】:

  • 存储搜索词是否更好是主观的。但它绝对可以工作。事实上,我们的一位工程师最近创建了一个在 Firestore 中存储三元组的搜索。顺便说一句:您的搜索词实际上也可以通过 Firestore 的内置搜索运算符找到:db.collection("brands").where("name", ">=", "adi").where("name", "<=", "adidas")
  • @FrankvanPuffelen 嗨,Puf!我们在哪里可以找到这个存储三元组的搜索?
  • 沿着完全相同的路径走下去,跳过了 1 和 3(因为我们需要完全控制并且它必须扩展),尝试了 Algolia 和 ElasticSearch。最终,在 SSR 上遇到了与 Algolia 相关的问题,然后尝试了 ElasticSearch 方法——到目前为止它进展顺利。我还不确定成本,因为我们仍在进行少量开发,但如果您对 Algolia 方法感兴趣,我写了一篇文章:link.medium.com/NNg0I3Usi1

标签: firebase google-cloud-firestore full-text-search


【解决方案1】:

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

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

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

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

您对在 Firestore 集合上执行模式过滤器有任何其他想法吗?

如果您有兴趣仅从单个单词中获取结果并使用品牌的注视字母作为模式,我建议您使用一个更好的解决方案,即使用如下所示的查询:

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

在这种情况下,像 aad 这样的搜索将非常有效。除此之外,无需创建任何其他数组。所以会有更少的文档写入。

【讨论】:

  • 感谢您的回答。我认为通过首字母搜索对我的项目来说已经足够了,这就是我考虑这个替代方案的原因。 + "\uf8ff" 是做什么的?
  • 不客气!查询中使用的字符 \uf8ff 是 Unicode 范围内的一个非常高的代码点(它是专用使用区 [PUA] 代码)。因为它在 Unicode 中的大多数常规字符之后,所以查询匹配所有以 searchName 开头的值。
  • 有没有让它不区分大小写?
  • @inorganik 通常我们都存储两者,就像我在这个 post 的回答中解释的那样。
  • @Alex Mamo 很棒的解决方案。但是如果我想要多个 orderBy 并且第一个 orderBy 是一个日期,我可以知道吗?
猜你喜欢
  • 2018-07-07
  • 2021-05-06
  • 2021-06-05
  • 1970-01-01
  • 2020-10-17
  • 2022-07-12
  • 2021-07-15
  • 2020-01-11
  • 1970-01-01
相关资源
最近更新 更多