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!)..equalTo('comedy')
vez de.startAt('comedy').endAt('comedy')
?Eu escrevi uma biblioteca pessoal que permite que você faça pedidos por vários valores, com todos os pedidos feitos no servidor.
Conheça Querybase!
O Querybase utiliza uma Referência do banco de dados do Firebase e uma matriz de campos que você deseja indexar. Quando você cria novos registros, ele manipula automaticamente a geração de chaves que permitem várias consultas. A ressalva é que ele suporta apenas equivalência direta (não menor que ou maior que).
fonte
fonte
A resposta de Frank é boa, mas o Firestore foi introduzido
array-contains
recentemente, o que facilita as consultas AND.Você pode criar um
filters
campo para adicionar seus filtros. Você pode adicionar quantos valores precisar. Por exemplo, para filtrar por comédia e Jack Nicholson, você pode adicionar o valor,comedy_Jack Nicholson
mas se você também quiser por comédia e 2014, pode adicionar o valorcomedy_2014
sem criar mais campos.fonte
O Firebase não permite consultas com várias condições. No entanto, eu encontrei uma maneira de contornar isso:
Precisamos baixar os dados filtrados iniciais do banco de dados e armazená-los em uma lista de arrays.
Depois de obtermos os dados filtrados iniciais do banco de dados, precisamos fazer mais filtros em nosso back-end.
fonte
Isso vai funcionar.
fonte