7
votes

Firestore: Comment interroger un objet cartographique dans une collection de documents?

Mon objectif:

L'application Web (similaire à Google Drive) dispose de 2 écrans.

Le premier écran est «Mon histoire» qui affiche tous les documents d'histoire dont je suis le propriétaire.

Le deuxième écran est «Partagé avec moi» qui affiche tous les documents d'histoire que je Je suis soit un lecteur, un écrivain ou un commentateur.

Nous avons ce /stories/{storyid}

db
.collection('stories')
.where(`roles.${uid}`, '==', 'owner')

Données complètes référence de la structure: https://firebase.google.com/docs/firestore/ solutions / accès basé sur les rôles

Question: Comment écrire la requête ci-dessous pour atteindre l'objectif ci-dessus?

{
  title: "A Great Story",
  content: "Once upon a time ...",
  roles: {
    alice: "owner",
    bob: "reader",
    david: "writer",
    jane: "commenter"
    // ...
  }
}

La requête ci-dessus ne fonctionne PAS car elle obligera Firestore à indexer les rôles.alice, roles.bob, roles.david, roles.jane et roles. [All_uid].


Modification n ° 1: Nous avons trouvé un message connexe (sans réponse) demandant à propos de Firestore interrogeant avec des rôles

p >


7 commentaires

Le lien que vous avez fourni concerne la sécurité, pas les requêtes. Si vous souhaitez interroger ce document par utilisateur, vous devrez alors l'indexer par utilisateur. Vous pouvez également restructurer vos données afin de pouvoir interroger des documents d'une manière qui n'exige pas que le nom de l'utilisateur soit un champ dans le document.


Donc, fondamentalement, vous voulez obtenir toutes les histoires où alice == propriétaire , non?


@AlexMamo Oui. Vous voulez obtenir toutes les histoires qui appartiennent à un UID (par exemple, Alice) qui est le propriétaire.


@DougStevenson Oui, le lien fourni concerne la sécurité. Cependant, le lien fait simplement référence à la structure de données fournie par votre équipe à titre d'exemple. En utilisant l'exemple de structure de données et en souhaitant effectuer des requêtes, il n'est pas logique d'indexer par utilisateur. Donc, s'il y a 1 000 000 d'utilisateurs, faut-il créer autant d'indices? En aucune façon! Alors, comment interroger des rôles dans un document qui peut renvoyer tous les documents appartenant à un user_id? par exemple. Alice.


Comme je l'ai dit, vous devrez utiliser une structure différente pour prendre en charge la requête que vous souhaitez effectuer. Il est courant dans les bases de données NoSQL de dupliquer des données pour différents besoins. Vous avez un besoin de sécurité, ce qui est bien. Vous avez maintenant un deuxième besoin, qui nécessite une deuxième solution.


@DougStevenson J'ai répondu à la question avec une réponse inspirée de votre commentaire. Pourriez-vous jeter un œil à la réponse et partager avec moi votre opinion?


@ choopage-JekBao Pouvez-vous expliquer comment la réponse acceptée a résolu ce problème? Merci


4 Réponses :


7
votes

4 commentaires

pouvez-vous commenter ma réponse. Je pense connaître la réponse à ma question.


S'il vous plaît voir mon commentaire ci-dessus. Je vais donc m'en tenir à cette réponse.


Qu'est-ce qui vous motive à répondre aux questions sur le SO? Juste curieux. Google / Firebase vous paie-t-il pour chaque réponse réussie?


@ choopage-JekBao Non. J'ai aussi été aidé une fois et j'aimerais aider les autres de la même manière;)



0
votes

Il n'est pas possible, par conséquent, nous devons dupliquer les données dans NoSQL.

Une structure de données possible est

/ stories / {storyid}

db
.collection('stories')
.where('shared', 'array_contains', uid)

Nous pouvons donc interroger l'interface utilisateur de l'application Web "Mon histoire"

db
.collection('stories')
.where('owner', '==', uid)

Alors que nous pouvons rechercher l'interface utilisateur de l'application Web "Partagé avec me '

{
  title: "A Great Story",
  content: "Once upon a time ...",
  roles: {
    alice: "owner",
    bob: "reader",
    david: "writer",
    jane: "commenter",
    mary: "writer",
    // ...
  },
  owner: "alice", // newly added
  shared: ["bob", "david", "jane", "mary"] // newly added
  // alice, bob, david, jane, mary are firebase auth uid
}

La réponse est inspirée des commentaires de @Doug Stevenson.


2 commentaires

@DougStevenson que pensez-vous de cette réponse?


Non, ce n'est pas une option puisque vous dupliquez des données dans le même document. Dans ce cas, qu'en est-il de la recherche de toutes les histoires jane == commenter ? Lorsque nous dupliquons des données, nous dupliquons le document entier, de sorte que nous pouvons copier exactement les mêmes données qui existent déjà à un endroit, à un autre, pour répondre à des requêtes qui ne seraient même pas possibles autrement. C'est exactement votre cas.



2
votes

 entrez la description de l'image ici S'il vous plaît laissez-moi savoir si je me trompe, mais il semble que votre requête devrait fonctionner. à titre expérimental, j'ai ajouté la structure que vous avez donnée dans la question et effectué la requête avec succès dans la console Firebase.

N'est-ce pas ce que vous recherchez? Je me suis également assuré que l'opérateur "in" fonctionne également pour ce cas. De cette façon, vous pouvez demander quelles histoires l'utilisateur est le propriétaire et le commentateur.

 entrez la description de l'image ici

Cela tire les bons résultats: entrez la description de l'image ici


4 commentaires

Avez-vous un index là-dessus?


Non, rien de plus n'a été configuré pour que cela fonctionne. Cela fonctionne hors de la boîte dans cet exemple.


J'ai essayé cela mais je n'ai pas réussi à obtenir mes résultats!


c'est ce que je recherche.



3
votes

Vous pouvez maintenant filtrer ...

db
  .collection('orders')
  .where('orderDetails.status', '==', 'OPEN')

Il vérifiera si le champ orderDetails de la propriété status est égal à "OPEN"


0 commentaires