问题描述
我正在尝试使用Firestore做三件事:
I'm trying to do three things using Firestore:
- 获取"contentType"字段为基本"的文档,
- 获取在特定时间点之后创建的文档.(在示例中为5AM.)
- 根据喜欢"计数排序文档.
contents
集合中的文档如下所示(省略了不必要的细节):
The documents in the contents
collection look like this (leaving out unnecessary details):
{
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子句不匹配.
The order(by: dateKey)
part is only necessary because Firebase demands it. Otherwise, an exception will be thrown, complaining that the where clause and the orderby clauses don't match.
我已经创建了一个复合索引,内容为 contentscontentType升序日期降序响应.例如降序
.
I already created a composite index that says contentscontentType Ascending date Descending response.like Descending
.
期望&结果
我希望这些文档按 like
计数进行排序,并且所有文档都是基本"类型,并在今天凌晨5点以后创建.
I'm expecting the documents to be ordered by the like
count, and all documents to be "basic" type and created past 5 a.m. of today.
相反,仅应用了前两个条件,而第三个条件被完全忽略.两个条件的不同组合起作用.这是三个条件组合不起作用的.
Instead, only the first two conditions are applied, and the third is completely ignored. Different mixes of two conditions work. It's the three conditions combined that is not working.
所以我的问题是,由于Firebase文档没有说关于两个以上的多重排序&在哪里组合,这是错误还是根本不可能的?
So my questions is, since Firebase documents don't say anything about having more than two multiple orderby & where combinations, is this a bug or something that's just not possible?
推荐答案
我找到了解决该问题的方法.
I found a workaround to the problem.
原始查询需要三个字段的复合索引.因此,在 date
上只有一个范围比较 – contentType
仅用于相等性检查,而在 date
和 response.like
,它们都构成了复合索引.
The original query required a composite index of three fields. So there is only one range comparison on date
--contentType
is used only for equality check--and two ordering on date
and response.like
, both of which compose the composite index.
相反,我决定像这样在 contents
文档中添加一个字段:
Instead I decided to add a field in the contents
document like so:
{
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
字符串.)
(Date.getDatabaseKey()
just creates a yyyy-MM-dd
string based on the current date.)
此查询需要两个复合索引:
This query requires two composite indexes:
标记数组的响应(如降序)
和 contentType升序的响应(如降序
).
幸运的是,这就像一个护身符.
Fortunately, this works like a charm.
添加的信息原始查询检查了集合中是否有某天凌晨5点之后创建的文档,对我而言,范围检查似乎是问题所在.
Added InfoThe original query checked the collection for documents created after 5 AM of a certain day, and to me the range check seemed to be the problem.
只要上面的 Date.getDatabaseKey()
方法生成的密钥与当天的5:00:00到第二天的 4:59:59的时间相同,此新查询的效果基本上相同.
As long as the Date.getDatabaseKey()
method above generates a key with the same day for hours 5:00:00 to 4:59:59 of the next day, this new query has basically the same effect.
这篇关于iOS-Firestore复合索引中索引的多个orderBy和where子句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!