Je pensais avoir lu que vous pouviez interroger des sous-groupes avec le nouveau Firebase Firestore, mais je ne vois aucun exemple. Par exemple, ma configuration Firestore est la suivante:
Comment pourrais-je interroger "Trouver toutes les danses où songName == 'X'"
C'est une fonctionnalité qui n'existe pas encore. Cela s'appelle une "requête de groupe de collection" et vous permettrait d'interroger toutes les chansons, quelle que soit leur danse. C’est quelque chose que nous avons l’intention de soutenir mais nous n’avons pas de calendrier précis à venir.
À ce stade, la structure alternative consiste à faire des chansons une collection de premier plan et à définir dans quelle danse la chanson fait partie d’une propriété de la chanson.
UPDATE Maintenant Firestore supporte les tableaux
Avoir ces documents
{danceName: 'Danca name 1', songName: ['Title1','Title2']}
{danceName: 'Danca name 2', songName: ['Title3']}
le faire de cette façon
collection("Dances")
.where("songName", "array-contains", "Title1")
.get()...
@ Nelson.b.austin Étant donné que Firestore ne l’a pas encore, je vous suggère d’avoir une structure plate, ce qui signifie:
Dances = {
danceName: 'Dance name 1',
songName_Title1: true,
songName_Title2: true,
songName_Title3: false
}
Ainsi, vous pouvez le faire:
var songTitle = 'Title1';
var dances = db.collection("Dances");
var query = dances.where("songName_"+songTitle, "==", true);
J'espère que ça aide.
Que faire si vous stockez des chansons sous forme d'objet plutôt que sous forme de collection? Chaque danse en tant que, avec les chansons comme un champ: tapez Object (pas une collection)
{
danceName: "My Dance",
songs: {
"aNameOfASong": true,
"aNameOfAnotherSong": true,
}
}
alors vous pouvez interroger toutes les danses avec aNameOfASong:
db.collection('Dances')
.where('songs.aNameOfASong', '==', true)
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
Comme l’a déclaré Gil Gilbert, il semble que les requêtes collection group soient actuellement en cours. En attendant, il est probablement préférable d'utiliser des collections de niveau racine et de simplement relier ces collections en utilisant les UID du document.
Pour ceux qui ne le savent pas encore, Jeff Delaney a des guides et des ressources incroyables pour tous ceux qui travaillent avec Firebase (et Angular) sur AngularFirebase .
Firestore NoSQL Relational Data Modeling - Il explique ici les bases de la structuration de bases de données NoSQL et Firestore
Modélisation de données avancée avec Firestore par exemple - Ce sont des techniques plus avancées pour garder à l'esprit. Une excellente lecture pour ceux qui souhaitent améliorer leurs compétences en matière de Firestore
Limites de la requête
Cloud Firestore ne prend pas en charge les types de requête suivants:
Requêtes avec filtres de plage sur différents champs.
Requêtes uniques sur plusieurs collections ou sous-collections. Chaque requête est exécutée sur une seule collection de documents. Pour plus des informations sur la manière dont votre structure de données affecte vos requêtes, voir Choisissez une structure de données .
- Requêtes logiques OR. Dans ce cas, vous devez créer une requête distincte pour chaque condition OR et fusionner les résultats de la requête dans votre application.
- Requêtes avec une clause! =. Dans ce cas, vous devez scinder la requête en une requête supérieure à et une requête inférieure à. Par exemple, bien que la clause de requête où ("age", "! =", "30") n'est pas supportée, vous pouvez obtenir le même jeu de résultats en combinant deux requêtes, une avec la clause où ("âge", "<", "30") et un avec la clause où ("âge", ">", 30).
var songs = []
db.collection('Dances')
.where('songs.aNameOfASong', '==', true)
.get()
.then(function(querySnapshot) {
var songLength = querySnapshot.size
var i=0;
querySnapshot.forEach(function(doc) {
songs.Push(doc.data())
i ++;
if(songLength===i){
console.log(songs
}
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
NEW UPDATE 8 juillet 2019:
db.collectionGroup('Songs')
.where('songName', isEqualTo:'X')
.get()
Il pourrait être préférable d’utiliser une structure de données plate.
La documentation précise les avantages et les inconvénients de différentes structures de données sur cette page .
Spécifiquement sur les limitations des structures avec des sous-collections:
Vous ne pouvez pas facilement supprimer des sous-groupes ou effectuer des requêtes composées sur plusieurs sous-groupes.
Contrasté avec les prétendus avantages d’une structure de données plate:
Les collections de niveau racine offrent une flexibilité et une évolutivité maximales, ainsi que des requêtes puissantes au sein de chaque collection.
Vous pouvez toujours chercher comme ceci: -
this.key$ = new BehaviorSubject(null);
return this.key$.switchMap(key =>
this.angFirestore
.collection("dances").doc("danceName").collections("songs", ref =>
ref
.where("songName", "==", X)
)
.snapshotChanges()
.map(actions => {
if (actions.toString()) {
return actions.map(a => {
const data = a.payload.doc.data() as Dance;
const id = a.payload.doc.id;
return { id, ...data };
});
} else {
return false;
}
})
);