iOS - Firestore несколько предложений orderBy и where для индексов в составном индексе - PullRequest
0 голосов
/ 03 февраля 2019

Я пытаюсь сделать три вещи, используя Firestore:

  • получить документы, у которых поле "contentType" имеет значение "basic",
  • получить документы, созданные после определенной точкиво время.(5 утра в примере.)
  • упорядочить документы в соответствии со счетом «like».

Документы в коллекции 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 не совпадают.

Я уже создал составной индекс, который говорит contents contentType Ascending date Descending response.like Descending.

Ожидание и результаты

Я ожидаю, что документы будут упорядочены по количеству like, а все документы будут иметь "базовый" тип и будут созданы после 5Я сегодня.

Вместо этого применяются только первые два условия, а третье полностью игнорируется.Работают разные смеси двух условий.Это три комбинированных условия, которые не работают.

Так что мои вопросы таковы, что в документах Firebase ничего не говорится о наличии более двух множественных комбинаций order & where, это ошибка или что-то, что просто невозможно

1 Ответ

0 голосов
/ 03 февраля 2019

Я нашел решение этой проблемы.

Для исходного запроса требовался составной индекс из трех полей.Таким образом, существует только одно сравнение диапазонов на 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 на основе текущей даты.)

Для этого запроса требуется два составных индекса:

tags Arrays response.like Descending и contentType Ascending response.like Descending.

К счастью, это работает как брелок.

Добавлена ​​информация Исходный запрос проверил коллекцию на наличие документов, созданных после 5 часов утра определенного дня, и мне показалось, что проверка диапазона была проблемой.

Пока вышеописанный метод Date.getDatabaseKey() генерирует ключ с тем же днем ​​для часов с 5:00:00 до 4: 59: 59 следующего дня , этот новый запрос имеетв основном тот же эффект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...