Consulte com filtros de intervalo e desigualdade na vista geral de várias propriedades

O Firestore no modo Datastore suporta a utilização de filtros de intervalo e de desigualdade em várias propriedades numa única consulta. Esta funcionalidade oferece-lhe condições de intervalo e desigualdade em várias propriedades e simplifica o desenvolvimento da sua aplicação delegando a implementação da lógica de pós-filtragem no Firestore no modo Datastore.

Filtros de intervalo e desigualdade em várias propriedades

A seguinte consulta usa filtros de intervalo na prioridade e nos dias para devolver todas as tarefas com uma prioridade superior a quatro e com menos de três dias para concluir.

Ir

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 a indexação

Antes de começar a executar consultas, certifique-se de que leu informações sobre as consultas.

Se não for especificada uma cláusula ORDER BY, o Firestore no modo Datastore usa qualquer índice que possa satisfazer a condição de filtro da consulta para publicar a consulta. Esta 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, otimize a ordem das propriedades no índice. Para isso, certifique-se de que o índice está ordenado da esquerda para a direita, de modo que a consulta seja reduzida a um conjunto de dados que impeça a análise de entradas de índice estranhas.

Por exemplo, suponhamos que quer pesquisar numa coleção de funcionários para encontrar funcionários dos Estados Unidos cujo salário seja superior a 100 000 $e cujo número de anos de experiência seja superior a 0. Com base na sua compreensão do conjunto de dados, sabe que a restrição de salário é mais seletiva do que a restrição de experiência. Um índice que reduz o número de análises de índice é o índice (salary [...], experience [...]). Como resultado, uma consulta rápida e rentável de encomendas salary antes de experience, conforme mostrado no exemplo seguinte:

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

Quando otimizar os índices, tenha em atenção as seguintes práticas recomendadas.

Ordene as consultas por igualdades, seguidas do campo de intervalo ou desigualdade mais seletivo

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 e desigualdade, se existir, no primeiro campo da consulta orderBy(). Estas restrições podem reduzir o número de entradas de índice que o Firestore no modo Datastore analisa. O Firestore no modo Datastore usa as propriedades restantes do índice para satisfazer outras restrições de intervalo e desigualdade da consulta. Estas restrições não reduzem o número de entradas de índice que o Firestore no modo Datastore analisa, mas filtram as entidades não correspondentes para que o número de entidades devolvidas aos clientes seja reduzido.

Para mais informações sobre a criação de índices eficientes, consulte a estrutura e a definição do índice e a otimização de índices.

Ordene as propriedades por ordem decrescente de seletividade da restrição de consulta

Para garantir que o Firestore no modo Datastore seleciona o índice ideal para a sua consulta, especifique uma cláusula orderBy() que ordene as propriedades de intervalo e de desigualdade com base na seletividade das respetivas restrições na sua consulta, começando pela mais seletiva. Uma seletividade mais elevada corresponde a menos entidades, enquanto uma seletividade mais baixa corresponde a mais entidades. Na ordenação de índices, coloque propriedades de intervalo e desigualdade com maior seletividade antes de propriedades com menor seletividade.

Para minimizar o número de entidades que o Firestore no modo Datastore analisa e devolve através da rede, deve ordenar sempre as propriedades por ordem decrescente da seletividade da restrição da consulta. Se o conjunto de resultados não estiver na ordem necessária e o conjunto de resultados for pequeno, pode implementar uma lógica do lado do cliente para reordená-lo de acordo com a sua expetativa de ordenação.

Por exemplo, se quiser pesquisar numa coleção de funcionários para encontrar funcionários dos Estados Unidos cujo salário seja superior a 100 000 $e ordenar os resultados pelo ano de experiência do funcionário. Se esperar que apenas um pequeno número de funcionários tenha um salário superior a 100 000 €, uma forma 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`

Embora a adição de uma ordenação em experience à consulta produza o mesmo conjunto de entidades e evite a reordenação dos resultados nos clientes, a consulta pode ler muito mais entradas de índice estranhas do que a consulta anterior. Isto acontece porque o Firestore no modo Datastore prefere sempre um índice cujas propriedades de índice correspondam ao prefixo da cláusula order by da consulta. Se experience fosse adicionado à cláusula ORDER BY, o Firestore no modo Datastore selecionaria o índice (experience [...], salary [...]) para calcular os resultados da consulta. Uma vez que não existem outras restrições em experience, o Firestore no modo Datastore lê todas as entradas de índice da coleção employees antes de aplicar o filtro salary para encontrar o conjunto de resultados final. Isto significa que as entradas de índice que não satisfazem o filtro salary são lidas na mesma, o que aumenta 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 obter informações detalhadas, consulte a página Preços.

Limitações

Além das limitações de consultas, tenha em atenção 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 demasiado caras para executar, o Firestore no modo Datastore limita o número de operadores de intervalo ou de desigualdade a 10.

O que se segue