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!)..equalTo('comedy')
place de.startAt('comedy').endAt('comedy')
?J'ai écrit une bibliothèque personnelle qui vous permet de trier par plusieurs valeurs, avec toutes les commandes effectuées sur le serveur.
Rencontrez Querybase!
Querybase prend une référence de base de données Firebase et un tableau de champs que vous souhaitez indexer. Lorsque vous créez de nouveaux enregistrements, il gère automatiquement la génération de clés qui permettent plusieurs requêtes. La mise en garde est qu'elle ne prend en charge que l'équivalence droite (ni inférieure ni supérieure à).
la source
la source
La réponse de Frank est bonne, mais Firestore a
array-contains
récemment introduit ce qui facilite les requêtes ET.Vous pouvez créer un
filters
champ pour ajouter vos filtres. Vous pouvez ajouter autant de valeurs que vous le souhaitez. Par exemple, pour filtrer par comédie et Jack Nicholson, vous pouvez ajouter la valeur,comedy_Jack Nicholson
mais si vous le souhaitez également par comédie et 2014, vous pouvez ajouter la valeurcomedy_2014
sans créer plus de champs.la source
Firebase n'autorise pas les requêtes avec plusieurs conditions. Cependant, j'ai trouvé un moyen de contourner cela:
Nous devons télécharger les données filtrées initiales de la base de données et les stocker dans une liste de tableaux.
Une fois que nous avons obtenu les données filtrées initiales de la base de données, nous devons effectuer un filtrage supplémentaire dans notre backend.
la source
Cela fonctionnera.
la source