O Firestore no modo Datastore oferece suporte ao uso de filtros de intervalo e desigualdade em várias propriedades em uma única consulta. Esse recurso oferece condições de intervalo e desigualdade em várias propriedades e simplifica o desenvolvimento de aplicativos delegando a implementação da lógica pós-filtragem ao Firestore no modo Datastore.
Filtros de intervalo e desigualdade em várias propriedades
A consulta a seguir usa filtros de intervalo de prioridade e dias para retornar todas as tarefas com prioridade maior que quatro e com menos de três dias para conclusão.
Go
query := datastore.NewQuery("Task").
FilterField("priority", ">", 4).
FilterField("days", "<", 3).
GQL
SELECT * FROM /tasks WHERE priority > 4 AND days < 3;
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("Task")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("priority", 4), PropertyFilter.lt("days", 3)))
.build();
Node.js
const query = datastore
.createQuery('Task')
.filter(
and([
new PropertyFilter('priority', '>', 4),
new PropertyFilter('days', '<', 3),
])
);
Python
from google.cloud import datastore
client = datastore.Client()
query = client.query(kind="Task")
query.add_filter(filter=PropertyFilter("priority", ">", 4))
query.add_filter(filter=PropertyFilter("days", "<", 3))
PHP
$query = $datastore->query()
->kind('Task')
->filter('priority', '>', 4)
->filter('days', '<', 3)
C#
Query query = new Query("Task")
{
Filter = Filter.And(Filter.GreaterThan("priority", 4),
Filter.LessThan("days", 3))
};
Ruby
query = datastore.query("Task")
.where("priority", ">", 4)
.where("days", "<", 3)
Considerações sobre indexação
Antes de começar a executar consultas, leia sobre consultas.
Se uma cláusula ORDER BY
não for especificada, o Firestore no modo Datastore vai usar qualquer índice que
possa atender à condição de filtro da consulta para exibir a consulta. Essa abordagem produz um conjunto
de resultados ordenado de acordo com a definição do índice.
Para otimizar o desempenho e o custo das consultas do Firestore no modo Datastore, otimizar a ordem das propriedades no índice. Para isso, verifique se o índice está ordenado da esquerda para a direita para que a consulta extraia um conjunto de dados que impeça a verificação de entradas de índice irrelevantes.
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 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. Um índice que reduz o número de verificações de índice é o
(salary [...], experience [...])
. Como resultado, uma consulta rápida e econômica
ordena salary
antes de experience
, conforme mostrado no exemplo a seguir:
GQL
SELECT *
FROM /employees
WHERE salary > 100000 AND experience > 0
ORDER BY salary, experience
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("salary", 100000), PropertyFilter.gt("experience", 0)))
.setOrderBy(OrderBy("salary"), OrderBy("experience"))
.build();
Node.js
const query = datastore
.createQuery("employees")
.filter(
and([
new PropertyFilter("salary", ">", 100000),
new PropertyFilter("experience", ">", 0),
])
)
.order("salary")
.order("experience");
Python
query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.add_filter("experience", ">", 0)
query.order = ["-salary", "-experience"]
Práticas recomendadas para otimizar índices
Ao otimizar os índices, observe as seguintes práticas recomendadas.
Ordenar consultas por igualdades seguidas pelo intervalo mais seletivo ou campo de desigualdade
O Firestore no modo Datastore usa as propriedades 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 orderBy()
. Essas restrições podem reduzir o número de
entradas de índice verificadas pelo Firestore no modo Datastore. O Firestore no modo Datastore usa as propriedades
restantes do índice para satisfazer outras restrições de intervalo e desigualdade da
consulta. Essas restrições não reduzem o número de entradas de índice que
o Firestore no modo Datastore verifica, mas filtram entidades sem correspondência para que o número de
entidades retornadas aos clientes seja reduzido.
Para mais informações sobre como criar índices eficientes, consulte Estrutura e definição de índices e Como otimizar índices.
Ordenar propriedades em ordem decrescente de seletividade de restrição de consulta
Para garantir que o Firestore no modo Datastore selecione o índice ideal para sua consulta,
especifique uma cláusula orderBy()
que ordene as propriedades de intervalo e desigualdade com base
em como as restrições são seletivas na consulta, começando pela mais
seletiva. Uma seletividade maior corresponde a menos entidades, enquanto uma seletividade menor
corresponde a mais entidades. Na ordem do índice, coloque propriedades de intervalo e desigualdade
com maior seletividade antes das propriedades com menor seletividade.
Para minimizar o número de entidades que o Firestore no modo Datastore verifica e retorna pela rede, sempre ordene as propriedades na ordem decrescente de seletividade de restrição de consulta. 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, se você quiser 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 ano de experiência do funcionário. Se você espera que apenas um pequeno número de funcionários tenha um salário superior a US $100.000, uma maneira eficiente de escrever a consulta é a seguinte:
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(PropertyFilter.gt("salary", 100000))
.setOrderBy(OrderBy("salary"))
.build();
QueryResults<Entity> results = datastore.run(query);
// Order results by `experience`
Node.js
const query = datastore
.createQuery("employees")
.filter(new PropertyFilter("salary", ">", 100000))
.order("salary");
const [entities] = await datastore.runQuery(query);
// Order results by `experience`
Python
query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.order = ["salary"]
results = query.fetch()
// Order results by `experience`
Adicionar uma ordenação em experience
à consulta vai gerar o mesmo conjunto
de entidades e evitar a reordenação dos resultados nos clientes, mas a consulta pode
ler muito mais entradas de índice irrelevantes do que a consulta anterior. Isso acontece porque
o Firestore no modo Datastore sempre prefere um índice cujo prefixo de propriedades de índice corresponda à
ordem por cláusula da consulta. Se experience
forem adicionados à ordem por uma cláusula,
o Firestore no modo Datastore vai selecionar o índice (experience [...], salary [...])
para calcular os resultados da consulta. Como não há outras restrições em
experience
, o Firestore no modo Datastore vai ler todas as entradas de índice da
coleção employees
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árias propriedades são faturadas com base nas entidades lidas e nas 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árias propriedades:
- Para evitar que as consultas se tornem muito caras para serem executadas, o Firestore no modo Datastore limita o número de operadores de intervalo ou desigualdade a 10.
A seguir
- Saiba mais sobre como otimizar suas consultas.
- Saiba mais sobre como realizar consultas simples e compostas.
- Entenda como o Firestore no modo Datastore usa índices.