Travailler avec des requêtes simples imbriquées dans Firestore
récemment j'ai déplacé mon modèle de données de Firebase à Firestore. Tout mon code fonctionne, mais j'ai de vilains problèmes concernant mes requêtes imbriquées pour récupérer des données. Voici le point:
aujourd'hui mon modèle de données pour cette partie ressemble à ça(Oui! Un autre des disciples/feed exemple):
{
"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
}
}
}
}
}
Mon problème est que pour récupérer les Postes de l'alimentation d'un utilisateur je dois requête de la façon suivante:
- obtenir le dernier x documents commander par timeStamp à partir de mon Alimentation
feedCol(userId).orderBy(CREATION_DATE, Query.Direction.DESCENDING).limit(limit)
Après que je devrais faire une requête unique de chaque post (extrait de la liste:
workoutPostCol.document(postId)
maintenant j'ai les données de chaque message, mais je veux filmer le nom d'utilisateur, l'image, les points.. etc de l'auteur, qui est dans un autre
Document
, donc, encore une fois je devrais faire une autre requête simple pour chaqueauthorId
extrait de la liste des postesuserSocial(userId).document(toId)
enfin, et ce n'est pas moins important, j'ai besoin de savoir si mon utilisateur actuel a déjà aimé ce post, donc je dois faire une seule requête pour chaque post(encore une fois) et vérifier si mon userId est à l'intérieur de
posts/likes/{userId}
en ce moment tout fonctionne, mais penser que le prix de Firestore
dépend du nombre d'appels de base de données, et aussi que cela ne rend pas mes requêtes plus simples, Je ne sais pas si c'est juste que mon modèle de données n'est pas bon pour ce type de base de données et je devrais aller à la normale SQL
ou en Firebase
nouveau.
Remarque:: je sais que TOUT serait beaucoup plus facile de déplacer cette sous-groupes de "j'aime", les aliments, etc, à arraylists à l'intérieur de mon utilisateur ou afficher les documents, mais la limite d'un Document 1 MO et si cela se développe beaucoup, il s'écrasera dans le futur. En revanche Firestore
ne pas autoriser les sous-requêtes(encore) ou un OR
utilisation d'une clause multiple whereEqualTo
.
j'ai lu beaucoup de messages d'utilisateurs qui ont des problèmes à la recherche d'un moyen simple de stocker ce type d' ID's
relation à faire joins
et queries
leurs Collections
, utilisez Arraylists
serait génial, mais la limite de 1 MO limiter à beaucoup.
J'espère que quelqu'un pourra clarifier cela, ou au moins m'enseigner quelque chose de nouveau; peut-être que mon modèle est juste de la merde et qu'il y a une façon simple et facile de le faire? Ou peut-être que mon modèle n'est pas possible pour un non-sql base de données.
1 réponses
pas sûr à 100% si cela résout entièrement le problème, car il peut y avoir des cas de bord pour votre usage. Mais avec une réflexion rapide de 5 min, j'ai l'impression que ce qui suit pourrait résoudre votre problème:
Vous pouvez envisager d'utiliser un modèle similaire à Instagram. Si ma mémoire me sert bien, ce qu'ils utilisent est un events
- collection basée. Par events
dans ce contexte précis, je veux dire toutes les actions que l'utilisateur prend. Donc un comment
est un événement, un like
est un événement.
Ce serait faire de sorte que vous aurez besoin de trois collections principales au total.
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's 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
Pour votre utilisateur-page bio, vous serait requête users
.
Pour les flux d'actualités, vous serait requête posts
tous les posts par les noms d'utilisateur est votre nom d'utilisateur suivant dans le dernier 1 jour (ou d'un timespan),
pour la page d'alimentation de l'activité (commentaires / j'aime etc.), vous auriez requête events
qui sont pertinents pour votre userID limité au dernier 1 jour (ou n'importe quelle durée donnée)
Enfin interrogez les prochains jours pour les messages / événements que l'utilisateur scrolls (ou s'il n'y a pas de nouvelle activité dans ces jours)
encore une fois, ce n'est qu'une pensée rapide, je sais que les aînés de SOF ont l'habitude de les crucifier d'habitude, alors pardonnez-moi les collègues de SOF si cette réponse a des défauts :)
j'Espère que ça aide Francisco,
Bonne chance!