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

iOS-Firestore复合索引中索引的多个orderBy和where子句,ios,swift,firebase,google-cloud-firestore,Ios,Swift,Firebase,Google Cloud Firestore,我尝试使用Firestore做三件事: 获取“contentType”字段为“basic”的文档 获取超过某个时间点创建的文档。(示例中为上午5点。) 根据“相似”计数订购文档 目录集合中的文档如下所示(省略不必要的细节): { 日期:时间戳; contentType:字符串; 答复:{ 比如:数字; }; } 以下是iOS代码: let dateKey = "date" let likeKey = "response.like" let startDate = Date().setLoc

我尝试使用Firestore做三件事:

  • 获取“contentType”字段为“basic”的文档
  • 获取超过某个时间点创建的文档。(示例中为上午5点。)
  • 根据“相似”计数订购文档
目录
集合中的文档如下所示(省略不必要的细节):

{
日期:时间戳;
contentType:字符串;
答复:{
比如:数字;
};
}
以下是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升序日期降序响应。如降序

期望和结果

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

相反,只应用前两个条件,而完全忽略第三个条件。两种条件的不同组合起作用。这三个条件加在一起不起作用


所以我的问题是,由于Firebase文档没有提到任何关于拥有两个以上的多个orderby&where组合的内容,这是一个错误还是不可能的事情?

我找到了解决问题的方法

原始查询需要三个字段的复合索引。因此,在
日期
上只有一个范围比较--
内容类型
仅用于相等性检查--在
日期
响应上有两个排序。如
,两者都构成了复合索引

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

{
标记:string[];//新字段。
日期:时间戳;
contentType:字符串;
答复:{
比如:数字;
};
}
新查询如下所示:

Firestore.Firestore()
.collection(路径:。内容)
.whereField(.tags,arrayContains:Date.getDatabaseKey())
.whereField(.contentType,isEqualTo:“基本”)
.顺序(按:likeKey,降序:true)
.limit(到:常量.fetchLimit)
Date.getDatabaseKey()
仅基于当前日期创建一个
yyyy-MM-dd
字符串。)

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

标记数组响应。如降序
内容类型升序响应。如降序

幸运的是,这很有魅力

添加信息 最初的查询检查了某一天早上5点之后创建的文档的集合,对我来说,范围检查似乎是个问题


只要上面的
Date.getDatabaseKey()
方法在第二天的5:00:00到4:59:59小时内生成一个当天的密钥,这个新查询的效果基本相同。

我找到了解决问题的方法

原始查询需要三个字段的复合索引。因此,在
日期
上只有一个范围比较--
内容类型
仅用于相等性检查--在
日期
响应上有两个排序。如
,两者都构成了复合索引

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

{
标记:string[];//新字段。
日期:时间戳;
contentType:字符串;
答复:{
比如:数字;
};
}
新查询如下所示:

Firestore.Firestore()
.collection(路径:。内容)
.whereField(.tags,arrayContains:Date.getDatabaseKey())
.whereField(.contentType,isEqualTo:“基本”)
.顺序(按:likeKey,降序:true)
.limit(到:常量.fetchLimit)
Date.getDatabaseKey()
仅基于当前日期创建一个
yyyy-MM-dd
字符串。)

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

标记数组响应。如降序
内容类型升序响应。如降序

幸运的是,这很有魅力

添加信息 最初的查询检查了某一天早上5点之后创建的文档的集合,对我来说,范围检查似乎是个问题


只要上面的
Date.getDatabaseKey()
方法在第二天的5:00:00到4:59:59小时内生成一个同一天的键,这个新查询的效果基本相同。

Firestore查询只能执行范围查询或按一个键排序。在您的情况下,这意味着您必须按照
dateKey
进行排序/筛选,或者按照
order
对结果进行排序,但两者都可以。这是有文档记录的,包括在和中。很抱歉,我阅读了文档,问题中只有一个范围过滤器,尽管有两种。文档说是一个范围过滤器,而不是排序。有两个where子句,但第一个是相等,而不是范围。我已经看到了你链接的问题,但它完全不同。@FrankvanPuffelen请检查我的评论。这不是重复项。您使用两个键进行排序(
.order(by:dateKey,descending:true)。order(by:likeKey,descending:true)
),由于Todd在我链接的视频中解释的原因,这是不可能的。Firestore查询只能执行范围查询或按一个键进行排序。在您的情况下,这意味着您必须按照
dateKey
进行排序/筛选,或者按照
order
对结果进行排序,但两者都可以。这是有文档记录的,包括在和中。很抱歉,我阅读了文档,问题中只有一个范围过滤器,尽管有两种。文档说是一个范围过滤器,而不是排序。有两个where子句,但第一个是相等,而不是范围。我