Firebase Firestore - Фильтрация данных с несколькими «массивами» - PullRequest
0 голосов
/ 11 июня 2019

Я изо всех сил пытаюсь найти хороший материал о передовых методах фильтрации данных с помощью firebase firestore.Я хочу отфильтровать свои данные на основе категорий, выбранных пользователем.У меня есть коллекция документов, хранящихся в моей базе данных пожарного магазина, и у каждого документа есть массив, в котором есть все соответствующие категории для этого отдельного документа.Ради фильтрации я держу локальный массив с предпочтительными для пользователя категориями.Все, что я хочу сделать, это отфильтровать данные по предпочтительным категориям пользователя.

поле категорий пожарного магазина

учтите, что предпочтительные категории пользователя хранятся в виде массиваstrings (["Film", "Music"]). Я планировал использовать метод 'array-includes' в firestore, например

db.collection(collectioname)
.where('categoriesArray', 'array-contains', ["Film", "Music"])

Позже я обнаружил, что не могу использовать 'array-contains'по отношению к самому массиву, и после изучения этой проблемы я решил изменить свою структуру данных, как указано здесь .

категории изменены на Map

После того, как я изменил категории с массива на карту, я подумал, что мог бы использовать несколько условий, чтобы фильтровать документы

let query = db.collection(collectionName)
      .where(somefield, '==', true)

this.props.data.filterCategories.forEach((val) => {
  query = query.where(`categories.${val}`, '==', true);
});

query = query
        .orderBy(someOtherField, "desc")
        .limit(itemsPerPage)

const snapshot = await query.get()

Теперь задача № 2, firebase требует добавления индексов для составных запросов.Категории, которые я сохранил в каждом документе, являются динамическими, и я не могу заранее добавить эти индексы.Каково было бы идеальное решение в таких случаях?Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

0 голосов
/ 11 июня 2019

Вместо того, чтобы выполнять итерацию по каждой категории, к которой вы хотите обратиться, и добавлять предложения к одному объекту query, каждая итерация должна представлять собой собственный независимый запрос.И вы можете хранить категории в массиве.

<document>
    - itemId: abc123
    - categories: [film, music, television]

Если вы хотите выполнить запрос OR, вы должны сделать n-циклы, где каждый цикл будет запрашивать документы, где массив содержит эту категорию.Затем, с вашей стороны, вы будете дедуплировать (удалять дубликаты) из результатов на основе идентификатора элемента.Поэтому, если вы хотите запросить фильм или музыку, вы должны сделать 2 цикла, где первая итерация запрашивает документы, где массив содержит фильм, и вторая петля запрашивает документы, где массив содержит музыку.Результаты будут помещены в одну коллекцию, а затем вы просто удалите все дубликаты с одинаковым itemId.

. Это также не создает проблемы с пределом составного индекса, поскольку categories является статическимполе.Настоящая проблема связана с разбиением на страницы, потому что вам нужно будет вести учет всех извлеченных itemId на случай, если будущая страница результатов вернет элемент, который уже был извлечен, и это создаст сценарий O (N ^ 2) (подробнее о больших-o запись: https://rob -bell.net / 2009/06 / a-beginners-guide-to-big-o-notation / ).А поскольку вы выполняете локальную дедупликацию, блоки нумерации страниц, как их видит пользователь, не обязательно будут четными.Если для каждого блока нумерации страниц установлено, например, 25 документов, на некоторых страницах может отображаться 24, некоторые 21, другие 14, в зависимости от того, сколько дубликатов было удалено из каждого блока.

0 голосов
/ 12 июня 2019

Ваш запрос включает предложение orderBy.Это в сочетании с любым фильтром равенства требует создания индекса для поддержки этого запроса.Этого избежать невозможно.

Если вы удалите orderBy, вы сможете использовать гибкие динамические фильтры на равенство, используя свойства карты в документе.Это единственный способ иметь динамический фильтр без создания индекса.Это, конечно, означает, что вам придется заказывать и публиковать результаты запроса на клиенте.

0 голосов
/ 11 июня 2019

Планируете ли вы получать документы с точным массивом категорий? Скажем, ваши предпочтения пользователя указаны как ["Film", "Music"]. Вы хотите получить только те документы, которые имеют Фильм И Музыка, или вы хотите получить документы, имеющие Фильм ИЛИ музыку?

Если это последнее, то, возможно, вы можете запросить все документы с помощью «Фильма», а затем запросить все документы с помощью «Музыки», а затем объединить его. Однако недостатком здесь является чтение некоторых избыточных документов, когда в таком документе есть и «Кино», и «Музыка» в поле categoryArray.

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

В первом случае я не сталкивался с работоспособным решением, кроме как хранить его в виде объединенной строки в алфавитном порядке? У других может быть более твердый раствор, чем у меня.

Надеюсь, это поможет!

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