本文介绍了iOS-Firestore复合索引中索引的多个orderBy和where子句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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子句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 07:25