Как я могу отфильтровать по дате и доступности в пожарном магазине?

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

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

let usersQuery = firestore.collection('Users')
                        .where('availableInAreaCodes.12345', '==', true)
                        .where('availableOnDates.2019-10-20', '==', true)
                        .orderBy('level', 'asc');

Любые идеи?


person Wadim Halik    schedule 12.10.2019    source источник


Ответы (2)


Спасибо @DougStevenson и @FrankvanPuffelen за вашу помощь.

Я нашел хороший компромисс между количеством документов, денормализацией и использованием чтения / записи.

Примечание. Это решение может не подходить для вашего сценария.

Я добавил новую подколлекцию «Доступность» к каждому пользовательскому документу и разделил данные о доступности на недели в году (старые документы удаляются каждую неделю, а новые добавляются каждую неделю).

Я добавил areaCodes в виде массива, каждый будний день в виде поля и сокращенный набор пользовательских данных в документы.

Мне пришлось создать в общей сложности 44 составных индекса (11 полей * 4 упорядоченных комбинации). Максимальное количество Firestore - 200 на базу данных.

По моему сценарию, оно того стоило, поскольку этот запрос является ключевой функцией приложения.

let usersQuery = firestore.collectionGroup('Availability')
                        .where('areaCodes', 'array-contains', 'DE-1234')
                        .where('weekYear', '==', '2019-W42'))
                        .where('monday', '==', 'available')
                        .orderBy('userPreview.level', 'asc'
person Wadim Halik    schedule 13.10.2019

Вы можете добавить массив, содержащий комбинацию доступных дат вашего пользователя и кода города:

availableInAreaCodesOnDates:
  ["12345_2019-10-20", "94110_2019-10-20"]

Затем вы можете запросить это с помощью одного оператора array-contains.

person Frank van Puffelen    schedule 12.10.2019
comment
Спасибо за ваш ответ. Я думал об этом, но отказался от этой идеи, потому что количество комбинаций быстро превысит 1 МБ, что является максимальным размером документа в базе данных firestore. - person Wadim Halik; 12.10.2019
comment
@wadimhalik Затем подумайте о том, чтобы поместить каждую комбинацию в отдельные документы в другой коллекции и запросить совпадения в этой подколлекции. - person Doug Stevenson; 12.10.2019