在云还原集合上按模式搜索



我正在尝试对 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");

所以我有几个问题:

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

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

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

您如何看待第 3 种解决方案的相关性和效率?

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

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

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

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

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

我还写了一篇文章,叫做:

  • 如何以更便宜的价格过滤Firestore数据?

这也可能有所帮助。

最新更新