Firestore: Работа с вложенными одиночными запросами
Недавно я переместил мою модель данных с
Firebase
на
Firestore
. Весь мой код работает, но у меня возникают некоторые уродливые проблемы в отношении моих вложенных запросов для получения некоторых данных. Вот пункт:
Прямо сейчас моя модель данных для этой части выглядит следующим образом (да! другой пример/пример подачи):
{
"Users": { //Collection
"UserId1" : { //Document
"Feed" : { //Subcollection of Id of posts from users this user Follow
"PostId1" : { //Document
"timeStamp" : "SomeDate"
},
"PostId2" : {
"timeStamp" : "SomeDate"
},
"PostId3" : {
"timeStamp" : "SomeDate"
}
}
//Some data
}
},
"Posts":{ //Collection
"PostId1":{ //Document
"Comments" :{ //Subcollection
"commentId" : { //Document
"authorId": "UserId1"
//comentsData
}
},
"Likes" : { //Subcollection
"UserId1" : { //Document
"liked" : true
}
}
}
}
}
Хорошо, теперь проблема заключается в том, что для извлечения сообщений фида пользователя я должен запросить следующим образом:
- Получите последний заказчик документов X по времени из моего фида.
feedCol(userId).orderBy(CREATION_DATE, Query.Direction.DESCENDING).limit(limit)
-
После этого я должен сделать один запрос каждого сообщения, полученного из списка: workoutPostCol.document(postId)
-
Теперь у меня есть данные каждого сообщения, но я хочу снять имя пользователя, картинку, точки и т.д. автора, который находится в другом Document
, поэтому снова нужно сделать еще один запрос для каждого authorId
, полученного в списке сообщений userSocial(userId).document(toId)
-
Наконец, и не менее важно, мне нужно знать, понравился ли мой текущий пользователь этой записи, поэтому мне нужно сделать один запрос для каждого сообщения (снова) и проверить, находится ли мой userId внутри posts/likes/{userId}
Сейчас все работает, но, думая, что цена Firestore
зависит от количества вызовов в базе данных, а также что это не делает мои запросы более простыми, я не знаю, просто ли это модель данных не подходит для такого типа базы данных, и я должен перейти в обычный SQL
или снова вернуться к Firebase
снова.
Примечание. Я знаю, что ВСЕ, было бы намного легче перемещать эти подколлекции понравившихся, фидов и т.д. к arraylists внутри моего пользователя или отправлять документы, но предел документа 1MB, и если это будет расти, то в будущем он рухнет. В другой руке Firestore
не разрешает запросы вложенного документа (пока) или предложение OR
, используя несколько whereEqualTo
.
Я прочитал много сообщений от пользователей, у которых есть проблемы с поиском простого способа сохранить этот вид отношения ID's
, чтобы сделать joins
и queries
в их Collections
, использовать Arraylists
будет удивительный, но предел 1 МБ ограничивает его.
Надеюсь, что кто-то сможет прояснить мой разум или, по крайней мере, научить меня чему-то новому, может быть, моя модель просто дерьмо, и есть простой и простой способ сделать это. Или, может быть, моя модель невозможна для базы данных, отличной от sql.
Спасибо всем за все, славный день.
Ответы
Ответ 1
Не 100% уверены, что это полностью решает проблему, так как для вашего использования могут быть крайние случаи. Но с быстрым мышлением 5 минут я чувствую, что следующее может решить вашу проблему:
Вы можете использовать модель, похожую на Instagram. Если моя память мне хорошо помогает, то она использует коллекцию на основе events
. Под events
в этом конкретном контексте я подразумеваю все действия, которые предпринимает пользователь. Таким образом, comment
- событие, a like
- событие и т.д.
Это сделает так, что вам понадобится три основных коллекции.
users
-- userID1
---- userdata (profile pic, bio etc.)
---- postsByUser : [postID1, postID2]
---- followedBy : [userID2, ... ]
---- following : [userID2, ... ]
-- userID2
---- userdata (profile pic, bio etc.)
posts
-- postID1 (timestamp, so it sortable)
---- contents
---- author : userID1
---- authorPic : authorPicUrl
---- authorPoints : 12345
---- taggedUsers : []
---- comments
------ comment1 : { copy of comment event }
---- likes : [userID1, userID2]
-- postID2 (timestamp)
---- contents
...
events
-- eventID1
---- type : comment
---- timestamp
---- byWhom : userID
---- toWhichPost : postID
---- contents : comment-text
-- eventID2
---- type : like
---- timestamp
---- byWhom : userID
---- toWhichPost : postID
Для вашей страницы пользователя-bio вы должны запросить users
.
Для новостной ленты вы запросите posts
для всех сообщений по идентификаторам пользователя, которые ваш пользователь выполняет за последний 1 день (или любой заданный промежуток времени),
Для страницы канала подачи (комментарии/пожелания и т.д.) вы должны запросить events
, которые имеют отношение к вашему идентификатору пользователя, ограниченному последним 1 днем (или любым заданным временем)
Наконец, запрашивайте следующие дни для сообщений/событий, когда пользователь прокручивает (или если в эти дни нет новой активности)
Опять же, это просто быстрая мысль, я знаю, что у старших из SOF есть привычка распинать их обычно, поэтому простите меня, товарищи из членов SOF, если этот ответ имеет недостатки:)
Надеюсь, это поможет Франциско,
Удачи!