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 chaque authorId extrait de la liste des postes userSocial(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.

27
demandé sur halfer 2017-10-13 10:46:51

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!

18
répondu johnozbay 2017-10-24 14:03:59