iOS - Firestore 复合索引中索引的多个 orderBy 和 where 子句

标签 ios swift firebase google-cloud-firestore

我正在尝试使用 Firestore 做三件事:

  • 获取“contentType”字段为“basic”的文档,
  • 获取在某个时间点之后创建的文档。 (示例中为凌晨 5 点。)
  • 根据“喜欢”数量对文档进行排序。

contents 集合中的文档如下所示(省略不必要的细节):

{
  date: Timestamp;
  contentType: string;
  response: {
    like: Number;
  };
}

这是 iOS 代码:

let dateKey = "date"
let likeKey = "response.like"
let startDate = Date().setLocalHour(5)
let timestamp = Timestamp(date: startDate)

Firestore.firestore()
    .collection(path: .contents)
    .whereField(.contentType, isEqualTo: "basic")
    .whereField(dateKey, isGreaterThanOrEqualTo: timestamp)
    .order(by: dateKey, descending: true)
    .order(by: likeKey, descending: true)
    .limit(to: Constant.fetchLimit)

order(by: dateKey) 部分是必需的,因为 Firebase 需要它。否则会抛出异常,提示 where 子句和 orderby 子句不匹配。

我已经创建了一个包含内容的复合索引 contentType 升序日期降序响应。如降序

期望与结果

我希望文档按 like 计数排序,并且所有文档都是“基本”类型并在今天早上 5 点之后创建。

相反,仅应用前两个条件,完全忽略第三个条件。两种条件的不同组合起作用。这三个条件结合在一起是行不通的。

所以我的问题是,由于 Firebase 文档没有说明有两个以上的多个 orderby 和 where 组合,这是一个错误还是根本不可能的事情?

最佳答案

我找到了解决该问题的方法。

原始查询需要三个字段的复合索引。因此在 date 上只有一个范围比较——contentType 仅用于相等检查——在date< 上有两个排序response.like,两者组成复合索引。

相反,我决定在 contents 文档中添加一个字段,如下所示:

{
  tags: string[]; // the new field.

  date: Timestamp;
  contentType: string;
  response: {
    like: Number;
  };
}

新查询看起来像这样:

Firestore.firestore()
    .collection(path: .contents)
    .whereField(.tags, arrayContains: Date.getDatabaseKey())
    .whereField(.contentType, isEqualTo: "basic")
    .order(by: likeKey, descending: true)
    .limit(to: Constant.fetchLimit)      

(Date.getDatabaseKey() 只是根据当前日期创建一个 yyyy-MM-dd 字符串。)

这个查询需要两个复合索引:

标签数组 response.like DescendingcontentType Ascending response.like Descending

幸运的是,这就像一个魅力。

添加信息 原始查询检查某天凌晨 5 点后创建的文档的集合,对我来说,范围检查似乎是问题所在。

只要上面的 Date.getDatabaseKey() 方法在同一天的 5:00:00 到次日 4:59:59 之间生成一个键,这个新查询的效果基本一样。

关于iOS - Firestore 复合索引中索引的多个 orderBy 和 where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54498407/

相关文章:

ios - 如何读取 iTunes 备份文件 (Manifest.db)

firebase - 如何将 Firebase 数据库与 Google 表格同步?

iOS - GitHub Firebase 身份验证

ios - 将两个变量传递给同一个 View Controller swift

ios - 使用 2 个或更多时,UITextField RightView 崩溃应用程序

ios - Apple 说 "Your iOS Distribution Certificate expiring"我需要做什么

ios - H。将Firebase添加到Flutter应用时找不到文件

ios - UICollectionCell 位置问题

ios - 使用 Swift Realm Results<> 或 List<> 实例时,如何避免延迟或调整 coordinator.drop 的时间?

ios - UIScrollView 内的 UIStackView,增长到最大高度然后滚动