Как запросить коллекцию Firestore для документов с полем, значение которого содержится в списке - PullRequest
0 голосов
/ 16 января 2019

У меня есть две коллекции Firestore, Users и Posts. Ниже приведены упрощенные примеры того, что содержится в каждом типичном документе.

enter image description here * Обратите внимание, что идентификаторы документов в подколлекции friends равны идентификаторам документов соответствующих пользовательских документов. При желании я также мог бы добавить поле uid к документам friends и / или документам Users. Кроме того, есть причина, не относящаяся к этому вопросу, что у нас есть friends в качестве подколлекции для каждого пользователя, но при необходимости мы превращаем ее в единую корневую коллекцию Friends.

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

Я достигаю этого в iOS / Swift с помощью следующего, хотя мы создаем это приложение для iOS, Android, и web.

guard let uid = Auth.auth().currentUser?.uid else {
    print("No UID")
    return
}
let firestoreUserRef = firestore.collection("Users").document(uid)
firestorePostsQuery = firestore.collection("Posts").whereField("owner", isEqualTo: firestoreUserRef).order(by: "timestamp", descending: true).limit(to: 25)

Мой вопрос заключается в том, как запросить Posts документы, которые имеют значения owner, содержащиеся в пользовательской коллекции friends, отсортированной в хронологическом порядке. Другими словами, как получить посты, принадлежащие друзьям пользователя, отсортированные в хронологическом порядке.

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

Теперь я знаю из документации , что Firestore не поддерживает логические ИЛИ-запросы, поэтому я не могу просто связать всех друзей вместе. Даже если бы я мог, это не кажется оптимальным подходом для тех, у кого больше горстки друзей.

Единственный вариант, который я могу придумать, - создать отдельный запрос для каждого друга. Однако есть несколько проблем с этим. Первая - это проблемы, представляющие (плавно) результаты многих асинхронных выборок. Во-вторых, я не могу объединить данные в хронологическом порядке без повторной сортировки набора вручную на клиенте каждый раз, когда обновляется один из моментальных снимков запроса (т.е. обновление в реальном времени).

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

1 Ответ

0 голосов
/ 16 января 2019

Сортировка в хронологическом порядке проста, если вы используете метку времени Unix, например 1547608677790 с использованием метода .orderBy. Однако это оставляет вам потенциальную гору запросов для итераций (по одному на каждого друга).

Итак, я думаю, вы хотите переосмыслить схему хранилища данных.

Воспользуйтесь Облачными функциями для триггеров Firebase . Когда пишется новый пост, пусть облачная функция подсчитает, кто все должен его видеть. Каждый пользователь может иметь свойство типа массива, содержащее все unread-posts, read-posts и т. Д.

Нечто подобное будет быстрым и наименее затратным.

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