Usando la API de consulta de Firebase , puede tener la tentación de probar esto:
// !!! 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());
});
Pero como dice @RobDiMarco de Firebase en los comentarios:
múltiples orderBy()
llamadas arrojarán un error
Entonces mi código anterior no funcionará .
Sé de tres enfoques que funcionarán.
1. filtrar más en el servidor, hacer el resto en el cliente
Lo que puede hacer es ejecutar uno orderBy().startAt()./endAt()
en el servidor, extraer los datos restantes y filtrarlos en el código JavaScript de su cliente.
ref
.orderBy('genre')
.equalTo('comedy')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
if (movie.lead == 'Jack Nicholson') {
console.log(movie);
}
});
2. agregue una propiedad que combine los valores que desea filtrar
Si eso no es lo suficientemente bueno, debería considerar modificar / expandir sus datos para permitir su caso de uso. Por ejemplo: podría incluir género + plomo en una sola propiedad que solo usa para este filtro.
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_lead": "comedy_Jack Nicholson"
},...
Básicamente, está creando su propio índice de múltiples columnas de esa manera y puede consultarlo con:
ref
.orderBy('genre_lead')
.equalTo('comedy_Jack Nicholson')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
David East ha escrito una biblioteca llamada QueryBase que ayuda a generar tales propiedades .
Incluso podría hacer consultas relativas / de rango, supongamos que desea permitir consultas de películas por categoría y año. Usaría esta estructura de datos:
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_year": "comedy_1997"
},...
Y luego consulta las comedias de los 90 con:
ref
.orderBy('genre_year')
.startAt('comedy_1990')
.endAt('comedy_2000')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
Si necesita filtrar más allá del año, asegúrese de agregar las otras partes de fecha en orden descendente, por ejemplo "comedy_1997-12-25"
. De esta manera, el orden lexicográfico que Firebase hace en los valores de cadena será el mismo que el orden cronológico.
Esta combinación de valores en una propiedad puede funcionar con más de dos valores, pero solo puede hacer un filtro de rango en el último valor de la propiedad compuesta.
Una variante muy especial de esto es implementada por la biblioteca GeoFire para Firebase . Esta biblioteca combina la latitud y la longitud de una ubicación en un llamado Geohash , que luego se puede usar para realizar consultas de rango en tiempo real en Firebase.
3. crear un índice personalizado mediante programación
Otra alternativa es hacer lo que todos hemos hecho antes de agregar esta nueva API de consulta: crear un índice en un nodo diferente:
"movies"
// the same structure you have today
"by_genre"
"comedy"
"by_lead"
"Jack Nicholson"
"movie1"
"Jim Carrey"
"movie3"
"Horror"
"by_lead"
"Jack Nicholson"
"movie2"
Probablemente hay más enfoques. Por ejemplo, esta respuesta destaca un índice personalizado alternativo en forma de árbol: https://stackoverflow.com/a/34105063
orderBy()
se lance oficialmente la próxima semana, múltiples llamadas arrojarán un error, porque los clientes actualmente dan resultados inesperados. Es posible que por casualidad funcionó en su prueba, pero no está diseñado para funcionar de manera genérica (¡aunque nos encantaría agregarlo!).