【问题标题】:What is the effect of passing an array to Firestore database's orderBy clause?将数组传递给 Firestore 数据库 order By 子句有什么影响?
【发布时间】:2021-05-26 16:18:42
【问题描述】:

想象一下我的 Firestore 数据库中的文档代表食谱,每个文档都有一个“标签”字段,这是一个包含该食谱标签的数组(例如:辣味、法式、素食)。

当用户搜索一些标签时,我使用 array-contains-any 操作符来拉回包含至少一个用户搜索过的标签的所有食谱。然后,我按已匹配的标签数量对返回的文档进行排序。例如,如果用户搜索“香辣法国素食”,则“tags”字段包含所有这三个标签的文档首先出现,然后是“tags”字段包含其中两个标签的文档,等等。

我目前正在使用手动排序:

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 按匹配标签的数量排序将文档返回给我,或者是我现在这样做的方式(在拉回具有至少一个匹配标签的所有文档后手动排序)唯一的办法?

【问题讨论】:

    标签: flutter google-cloud-firestore


    【解决方案1】:

    文档返回的顺序通常与文档在正在搜索的索引中出现的顺序相同。假设您的标签是字符串,那么根据data types 上的文档,那就是:

    UTF-8 编码字节顺序

    所以我希望它是它匹配的第一个标签的顺序,而不是您希望的匹配标签的数量。这种基于计算值的结果优先级根本不是 Firestore 查询的对象,因为它需要 Firestore 在将匹配项返回给您之前重新排序。

    【讨论】:

    • 谢谢。你打算用什么词来描述订单? “通常”之后好像少了一个词
    • 不,它实际上是完整的,只是有点难以解析。我试图澄清,虽然现在有点罗嗦。
    • 感谢您的澄清。只是为了确认一下,如果您遇到这个问题,您会按照我当时的方式实施它吗? (拉回所有至少有一个搜索标签的文档并手动排序)
    • 不幸的是,这使得分页变得不可能,所以我要么跳过该功能,要么寻找一种方法来公开并不意味着对动态计算值进行排序的功能。如果您需要比 Firestore 提供的更强大的搜索,请考虑使用专用搜索引擎。
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 2018-06-11
    • 2019-04-14
    • 1970-01-01
    相关资源
    最近更新 更多