O Cloud Firestore oferece suporte ao uso de filtros de intervalo e desigualdade em vários campos em uma única consulta. É possível ter condições de intervalo e desigualdade em vários campos e simplificar o desenvolvimento de aplicativos delegando a implementação de lógica pós-filtragem para o Cloud Firestore:
Filtros de intervalo e desigualdade em vários campos
A consulta a seguir usa filtros de intervalo de população e densidade para retornar todas as cidades em que a população é maior que 1.000.000 e a densidade populacional é menor que 10.000 pessoas por unidade de área.
Modular versão 9 para a Web
const q = query(
collection(db, "cities"),
where('population', '>', 1000000),
where('density', '<', 10000),
);
Swift
let query = db.collection("cities")
.whereField("population", isGreaterThan: 1000000)
.whereField("density", isLessThan: 10000)
Objective-C
FIRQuery *query =
[[[[self.db collectionWithPath:@"cities"]
queryWhereField:@"population" isGreaterThan:@1000000]
queryWhereField:@"density" isLessThan:@10000];
Java Android
Query query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Kotlin+KTX Android
val query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000)
Go
query := client.Collection("cities").
Where("population", ">", 1000000).
Where("density", "<", 10000)
Java
db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Node.js
db.collection("cities")
.where('population', '>', 1000000),
.where('density', '<', 10000)
Python
from google.cloud import firestore
db = firestore.Client()
query = db.collection("cities")
.where("population", ">", 1000000)
.where("density", "<", 10000)
PHP
C#
Ruby
query = cities_ref.where("population", ">", "1000000")
.where("density", "<", 10000)
C++
CollectionReference cities_ref = db->Collection("cities");
Query query = cities_ref.WhereGreaterThan("population", FieldValue::Integer(1000000))
.WhereLessThan("density", FieldValue::Integer(10000));
Unity
CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef.WhereGreaterThan("population", 1000000)
.WhereLessThan("density", 10000);
Dart
final citiesRef = FirebaseFirestore.instance.collection('cities')
final query = citiesRef.where("population", isGreaterThan: 1000000)
.where("density", isLessThan: 10000);
Considerações sobre indexação
Antes de executar as consultas, leia sobre consultas e o modelo de dados do Cloud Firestore.
No Cloud Firestore, a cláusula ORDER BY
de uma consulta determina quais índices podem ser usados para exibir a consulta. Por exemplo, uma consulta ORDER BY a ASC, b ASC
requer um índice composto nos campos a ASC, b ASC
.
Para otimizar o desempenho e o custo das consultas do Cloud Firestore, otimize a ordem dos campos no índice. Para isso, você deve garantir que seu índice seja ordenado da esquerda para a direita para que a consulta extraia um conjunto de dados que impede a verificação de entradas de índice irrelevantes.
Suponha que você queira pesquisar em um grupo de funcionários e encontrar funcionários dos Estados Unidos com salário superior a US$ 100.000 e número de anos de experiência maior do que zero. Com base em sua compreensão do conjunto de dados, você sabe que
a restrição salarial é mais seletiva do que a restrição de experiência. O índice
ideal que reduziria o número de verificações de índice seria o
(salary [...], experience [...])
: Assim, a consulta que seria rápida e
mais econômica pediria salary
antes de experience
e ficaria assim:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Node.js
db.collection("employees")
.where("salary", ">", 100000)
.where("experience", ">", 0)
.orderBy("salary")
.orderBy("experience");
Python
db.collection("employees")
.where("salary", ">", 100000)
.where("experience", ">", 0)
.order_by("salary")
.order_by("experience");
Práticas recomendadas para otimizar índices
Ao otimizar os índices, observe as seguintes práticas recomendadas.
Ordenar campos de índice por igualdades seguidas pelo intervalo mais seletivo ou campo de desigualdade
O Cloud Firestore usa os campos mais à esquerda de um índice composto para satisfazer as restrições de igualdade e a restrição de intervalo ou desigualdade, se houver, no primeiro campo da consulta do orderBy()
. Essas restrições podem reduzir o número de entradas de índice verificadas pelo Cloud Firestore. O Cloud Firestore usa os campos restantes do índice para satisfazer outras restrições de intervalo ou desigualdade da consulta. Essas restrições não reduzem o número de entradas de índice que o Cloud Firestore verifica, mas filtra documentos sem correspondência para que o número de documentos retornados aos clientes seja reduzido.
Para mais informações sobre como criar índices eficientes, consulte Propriedades de índice.
Ordenar campos em ordem decrescente de seletividade de restrição de consulta
Para garantir que o Cloud Firestore selecione o índice ideal para sua consulta, especifique uma cláusula orderBy()
que ordena os campos em ordem decrescente deseletividade de restrição. Maior seletividade corresponde a um subconjunto menor de
documentos, enquanto a menor seletividade corresponde a um subconjunto maior de documentos. Verifique se
você selecionou campos de intervalo ou desigualdade com maior seletividade no início do índice
do que campos com menor seletividade.
Para minimizar o número de documentos verificados e retornados pelo Cloud Firestore na rede, você sempre deve ordenar os campos na ordem decrescente de consulta de seletividade de restrição. Se o conjunto de resultados não estiver na ordem exigida e o resultado for pequeno, você pode implementar a lógica do lado do cliente para reordená-lo de acordo com sua expectativa de ordem.
Por exemplo, suponha que você queira pesquisar um conjunto de funcionários para encontrar funcionários dos Estados Unidos com salário superior a US$ 100.000 e ordenar os resultados pelo tempo de experiência do funcionário. Se você espera que apenas um pequeno número de funcionários tenha salários superiores a US$ 100.000, a maneira mais eficiente de escrever a consulta é a seguinte:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.orderBy("salary")
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
// Order results by `experience`
}
});;
Node.js
const querySnapshot = await db.collection('employees')
.where("salary", ">", 100000)
.orderBy("salary")
.get();
// Order results by `experience`
Python
results = db.collection("employees")
.where("salary", ">", 100000)
.order_by("salary")
.stream()
// Order results by `experience`
Adicionar uma ordenação em experience
à consulta produzirá o mesmo conjunto
de documentos e evita a reordenação dos resultados nos clientes, a consulta poderá
ler muito mais entradas de índice irrelevantes do que a consulta anterior. Isso acontece porque o Cloud Firestore sempre prefere um índice cujo prefixo de campos de índice corresponda à ordem por cláusula da consulta. Se experience
forem adicionados à ordem por uma cláusula, o Cloud Firestore vai selecionar o índice (experience [...], salary [...])
para calcular os resultados da consulta. Como não há outras restrições emexperience
, o Cloud Firestore lerá todas as entradas de índice da coleçãoemployees
antes de aplicar o filtro salary
para encontrar o resultado final de conjunto de resultados. Isso significa que as entradas de índice que não atendem aos critérios salary
são lidos, aumentando assim a latência e o custo da consulta.
Preços
As consultas com filtros de intervalo e desigualdade em vários campos são faturadas com base em documentos lidos e entradas de índice lidas.
Para informações detalhadas, consulte a página Preços.
Limitações
Além das limitações de consulta, observe as seguintes limitações antes de usar consultas com filtros de intervalo e desigualdade em vários campos:
- Consultas com filtros de intervalo ou desigualdade nos campos do documento e apenas restrições de igualdade na chave de documento no
(__name__)
não têm suporte. - O Cloud Firestore limita o número de campos de intervalo ou desigualdade a 10. Isso é para evitar que as consultas fiquem muito caras para execução.
A seguir
- Saiba mais sobre como otimizar suas consultas.
- Saiba mais sobre como realizar consultas simples e compostas.
- Entenda como o Cloud Firestore usa índices.