flutter - 将数组传递给 Firestore 数据库的 orderBy 子句有什么影响?
问题描述
想象一下,我的 Firestore 数据库中的文档代表食谱,每个文档都有一个“标签”字段,这是一个包含该食谱标签的数组(例如:辣味、法式、素食)。
当用户搜索一些标签时,我使用 array-contains-any 操作符来拉回所有包含至少一个用户搜索过的标签的食谱。然后,我按已匹配的标签数量对返回的文档进行排序。例如,如果用户搜索“香辣法国素食”,则“标签”字段包含所有这三个标签的文档首先出现,然后是“标签”字段包含其中两个标签的文档,等等。
我目前正在使用手动排序:
const userSearchedTags: string[] = [...] // array of tags searched for by user
recipes.sort((r1, r2) => {
const r1Tags: string[] = r1.get('tags');
const r2Tags: string[] = r2.get('tags');
const r1TagMatchQuant = r1Tags.filter(r1Tag => userSearchedTags.includes(r1Tag)).length;
const r2TagMatchQuant = r2Tags.filter(r2Tag => userSearchedTags.includes(r2Tag)).length;
return r2TagMatchQuant - r1TagMatchQuant;
});
但是我想对这个查询进行分页,这要求它们由 Firebase 排序,所以我想我可以在查询中使用 orderBy 子句,以便 Firebase 将已经按匹配标签数量排序的文档返回给我。如果这可行,那么我将能够使用 startAfter() 子句对我的查询进行分页。我试过这个:
FirebaseFirestore.instance
.collection('recipes')
.where('tags', arrayContainsAny: userSearchedTags)
.orderBy('tags')
.get();
但它不返回按匹配标签数排序的文档。我认为它可能会返回按每个文档上的“标签”数组的长度排序的文档,但进一步的测试表明它也没有这样做。所以我的问题是,当我将“标签”(一个数组字段)传递给 orderBy 子句时,Firebase 如何对这些文档进行排序?
此外,有没有办法让 Firebase 按匹配标签的数量排序将文档返回给我,或者我现在这样做的方式(在拉回具有至少一个匹配标签的所有文档后手动排序)唯一的方法?
解决方案
返回文档的顺序通常与文档出现在正在搜索的索引中的顺序相同。假设您的标签是字符串,那么根据数据类型的文档将是:
UTF-8 编码的字节顺序
所以我希望它是它匹配的第一个标签的顺序,而不是你希望的匹配标签的数量。这种基于计算值的结果优先级根本不是 Firestore 查询的目的,因为它需要 Firestore 在将匹配返回给您之前重新排序。
推荐阅读
- javascript - 使用带刻度的相同可重复字符串值
- php - 是否可以使用 php7(realpath 缓存和 opcache)提高 php 旧架构的性能?
- solidity - Superblocks :返回一个值并从 js 中的函数显示它。文件到智能合约
- python - Google Dataflow 是否支持使用 Python SDK 开发的有状态管道?
- python - 如何在 django 中将此基于函数的视图转换为基于类的视图
- c++ - DirectX 游戏引擎编译错误 LNK2019 和 LNK1120
- ruby-on-rails - Ruby on Rails 中的路由别名
- apache-spark - 我们可以使用 Spark 将数据移动到 Vertica,而无需使用 hadoop 作为暂存环境吗?
- java - 我无法在我的计算器中实现小数点
- mysql - 在#mysql 工作台中使用过程添加列时遇到问题