搜索名称的 Firestore 查询性能不佳
Firestore poor query performance searching names
我有一个使用 firestore 的小型 android 应用程序。我有一组文档(~5,000),其中每个文档都有一个“客户名称”。应用程序的要求之一是通过 contains 查询按客户名称搜索文档。 (即搜索词出现在名称中的任何位置)。
由于成本原因,我选择忽略 using a full text search solution 的建议,并决定通过在每个文档的数组字段中存储名称的排列来滚动我自己的建议,并且 运行ning 包含查询数组。
例如名字John Smith
,生成一个数组:[J, JO, JOH, JOHN, JOHN S, JOHN SM, JOHN SMI, JOHN SMIT, JOHN SMITH, S, SM, SMI, SMIT, SMITH]
。这是足够的排列,能够模拟名称中任何单词的“开头为”查询,这对我的用例来说已经足够了。
我在这个名为 searchTerms
的数组字段上创建了一个索引,并且 运行 查询如下:
query.whereArrayContains("searchTerms", term)
.orderBy("date", Query.Direction.Descending)
.limit(20)
这 运行 一开始还不错,但是我的客户开始抱怨搜索速度很慢。我 运行 在 android 上使用 query.get(Source.SERVER)
进行了一些测试,并定期获得最多 2 秒的查询时间。按短期搜索(例如 on
或 al
)产生的结果最慢。
我的问题是,这到底有多低效?做一些研究让我相信 it's not as inefficient as it looks on the surface。听起来数组中的每个元素都被添加到索引中,所以当我 运行 一个数组包含查询时,我是否只是在查询一个巨大的索引,它是我的集合的大小 * 平均数组大小?是索引大小减慢了查询速度吗?
最后,除了这个还有其他原生解决方案吗?
服务器上的 Firestore 查询按结果集的大小(即您检索的文档数)缩放,而不取决于集合中存在的文档数。针对客户端缓存的查询没有这种性能保证,因为它没有以相同的方式索引。
根据我们在评论中的讨论,听起来客户端缓存中可能包含此集合的大量文档,因此可以解释。启用缓存后,我建议始终使用 onSnapshot
侦听器,以便您同时获取本地数据(如果速度更快)和来自服务器的数据。
我最近描述了一些 Firestore 如何在服务器上逻辑地使用其索引,这也可能提供一些见解:
我有一个使用 firestore 的小型 android 应用程序。我有一组文档(~5,000),其中每个文档都有一个“客户名称”。应用程序的要求之一是通过 contains 查询按客户名称搜索文档。 (即搜索词出现在名称中的任何位置)。
由于成本原因,我选择忽略 using a full text search solution 的建议,并决定通过在每个文档的数组字段中存储名称的排列来滚动我自己的建议,并且 运行ning 包含查询数组。
例如名字John Smith
,生成一个数组:[J, JO, JOH, JOHN, JOHN S, JOHN SM, JOHN SMI, JOHN SMIT, JOHN SMITH, S, SM, SMI, SMIT, SMITH]
。这是足够的排列,能够模拟名称中任何单词的“开头为”查询,这对我的用例来说已经足够了。
我在这个名为 searchTerms
的数组字段上创建了一个索引,并且 运行 查询如下:
query.whereArrayContains("searchTerms", term)
.orderBy("date", Query.Direction.Descending)
.limit(20)
这 运行 一开始还不错,但是我的客户开始抱怨搜索速度很慢。我 运行 在 android 上使用 query.get(Source.SERVER)
进行了一些测试,并定期获得最多 2 秒的查询时间。按短期搜索(例如 on
或 al
)产生的结果最慢。
我的问题是,这到底有多低效?做一些研究让我相信 it's not as inefficient as it looks on the surface。听起来数组中的每个元素都被添加到索引中,所以当我 运行 一个数组包含查询时,我是否只是在查询一个巨大的索引,它是我的集合的大小 * 平均数组大小?是索引大小减慢了查询速度吗?
最后,除了这个还有其他原生解决方案吗?
服务器上的 Firestore 查询按结果集的大小(即您检索的文档数)缩放,而不取决于集合中存在的文档数。针对客户端缓存的查询没有这种性能保证,因为它没有以相同的方式索引。
根据我们在评论中的讨论,听起来客户端缓存中可能包含此集合的大量文档,因此可以解释。启用缓存后,我建议始终使用 onSnapshot
侦听器,以便您同时获取本地数据(如果速度更快)和来自服务器的数据。
我最近描述了一些 Firestore 如何在服务器上逻辑地使用其索引,这也可能提供一些见解: