En utilisant l'API de requête de Firebase , vous pourriez être tenté d'essayer ceci:
// !!! THIS WILL NOT WORK !!!
ref
.orderBy('genre')
.startAt('comedy').endAt('comedy')
.orderBy('lead') // !!! THIS LINE WILL RAISE AN ERROR !!!
.startAt('Jack Nicholson').endAt('Jack Nicholson')
.on('value', function(snapshot) {
console.log(snapshot.val());
});
Mais comme le dit @RobDiMarco de Firebase dans les commentaires:
plusieurs orderBy()
appels génèrent une erreur
Donc mon code ci-dessus ne fonctionnera pas .
Je connais trois approches qui fonctionneront.
1. filtrez le plus sur le serveur, faites le reste sur le client
Ce que vous pouvez faire est d'exécuter une orderBy().startAt()./endAt()
sur le serveur, de dérouler les données restantes et de les filtrer en code JavaScript sur votre client.
ref
.orderBy('genre')
.equalTo('comedy')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
if (movie.lead == 'Jack Nicholson') {
console.log(movie);
}
});
2. ajoutez une propriété qui combine les valeurs sur lesquelles vous souhaitez filtrer
Si cela ne suffit pas, vous devriez envisager de modifier / étendre vos données pour permettre votre cas d'utilisation. Par exemple: vous pouvez bourrer genre + lead dans une seule propriété que vous utilisez uniquement pour ce filtre.
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_lead": "comedy_Jack Nicholson"
},...
Vous créez essentiellement votre propre index multi-colonnes de cette façon et pouvez l'interroger avec:
ref
.orderBy('genre_lead')
.equalTo('comedy_Jack Nicholson')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
David East a écrit une bibliothèque appelée QueryBase qui aide à générer de telles propriétés .
Vous pouvez même faire des requêtes relatives / plage, disons que vous souhaitez autoriser l'interrogation des films par catégorie et par année. Vous utiliseriez cette structure de données:
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_year": "comedy_1997"
},...
Et puis recherchez des comédies des années 90 avec:
ref
.orderBy('genre_year')
.startAt('comedy_1990')
.endAt('comedy_2000')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
Si vous devez filtrer sur plus que l'année, assurez-vous d'ajouter les autres parties de date dans l'ordre décroissant, par exemple "comedy_1997-12-25"
. De cette façon, l'ordre lexicographique que Firebase fait sur les valeurs de chaîne sera le même que l'ordre chronologique.
Cette combinaison de valeurs dans une propriété peut fonctionner avec plus de deux valeurs, mais vous ne pouvez effectuer un filtre de plage que sur la dernière valeur de la propriété composite.
Une variante très spéciale de ceci est implémentée par la bibliothèque GeoFire pour Firebase . Cette bibliothèque combine la latitude et la longitude d'un emplacement dans un soi-disant Geohash , qui peut ensuite être utilisé pour effectuer des requêtes de portée en temps réel sur Firebase.
3. créer un index personnalisé par programme
Une autre alternative consiste à faire ce que nous avons tous fait avant l'ajout de cette nouvelle API de requête: créer un index dans un nœud différent:
"movies"
// the same structure you have today
"by_genre"
"comedy"
"by_lead"
"Jack Nicholson"
"movie1"
"Jim Carrey"
"movie3"
"Horror"
"by_lead"
"Jack Nicholson"
"movie2"
Il y a probablement plus d'approches. Par exemple, cette réponse met en évidence un autre index personnalisé en forme d'arbre: https://stackoverflow.com/a/34105063
orderBy()
appels généreront une erreur, car les clients donnent actuellement des résultats inattendus. Il est possible que cela ait coïncidé dans votre test, mais n'est pas conçu pour fonctionner de manière générique (bien que nous aimerions l'ajouter!).