Usando a API de consulta do Firebase , você pode tentar:
// !!! 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());
});
Mas como @RobDiMarco da Firebase diz nos comentários:
várias orderBy()
chamadas gerarão um erro
Portanto, meu código acima não funcionará .
Conheço três abordagens que funcionarão.
1. filtre mais no servidor, faça o resto no cliente
O que você pode fazer é executar um orderBy().startAt()./endAt()
no servidor, retirar os dados restantes e filtrá- los no código JavaScript do seu cliente.
ref
.orderBy('genre')
.equalTo('comedy')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
if (movie.lead == 'Jack Nicholson') {
console.log(movie);
}
});
2. adicione uma propriedade que combine os valores que você deseja filtrar
Se isso não for bom o suficiente, considere modificar / expandir seus dados para permitir seu caso de uso. Por exemplo: você pode agrupar gênero + lead em uma única propriedade que você acabou de usar para esse filtro.
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_lead": "comedy_Jack Nicholson"
},...
Você está basicamente criando seu próprio índice de várias colunas dessa maneira e pode consultá-lo com:
ref
.orderBy('genre_lead')
.equalTo('comedy_Jack Nicholson')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
David East escreveu uma biblioteca chamada QueryBase que ajuda na geração de tais propriedades .
Você pode até fazer consultas relativas / intervalo, digamos que deseja permitir a consulta de filmes por categoria e ano. Você usaria essa estrutura de dados:
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_year": "comedy_1997"
},...
E, em seguida, consulte as comédias dos anos 90 com:
ref
.orderBy('genre_year')
.startAt('comedy_1990')
.endAt('comedy_2000')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
Se você precisar filtrar mais do que apenas o ano, adicione as outras partes da data em ordem decrescente, por exemplo "comedy_1997-12-25"
. Dessa forma, a ordem lexicográfica que o Firebase realiza nos valores das strings será a mesma que a ordem cronológica.
Essa combinação de valores em uma propriedade pode funcionar com mais de dois valores, mas você só pode fazer um filtro de intervalo no último valor na propriedade composta.
Uma variante muito especial disso é implementada pela biblioteca GeoFire para Firebase . Essa biblioteca combina a latitude e longitude de um local em um chamado Geohash , que pode ser usado para fazer consultas de intervalo em tempo real no Firebase.
3. crie um índice personalizado programaticamente
Outra alternativa é fazer o que já fizemos antes da adição desta nova API de consulta: criar um índice em um nó 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"
Provavelmente existem mais abordagens. Por exemplo, esta resposta destaca um índice personalizado alternativo em forma de árvore: https://stackoverflow.com/a/34105063
orderBy()
chamadas gerarão um erro, porque os clientes atualmente fornecem resultados inesperados. É possível que funcionou coincidentemente em seu teste, mas não foi desenvolvido para funcionar de maneira genérica (embora adoraríamos adicioná-lo!).