Onde

Descrição

Filtra os documentos da etapa anterior, retornando apenas aqueles em que a condição é avaliada como true.

Sintaxe:

where(condition: Expr)

Exemplo

Crie uma coleção cities com os seguintes documentos:

Node.js

await db.collection('cities').doc('SF').set({name: 'San Francisco', state: 'CA', country: 'USA', population: 870000});
await db.collection('cities').doc('LA').set({name: 'Los Angeles', state: 'CA', country: 'USA', population: 3970000});
await db.collection('cities').doc('NY').set({name: 'New York', state: 'NY', country: 'USA', population: 8530000});
await db.collection('cities').doc('TOR').set({name: 'Toronto', state: null, country: 'Canada', population: 2930000});
await db.collection('cities').doc('MEX').set({name: 'Mexico City', state: null, country: 'Mexico', population: 9200000});

Faça uma pesquisa de igualdade:

Node.js

const cities = await db.pipeline()
  .collection("/cities")
  .where(field("state").equals("CA"))
  .execute();

Gera o seguinte resultado:

{name: 'San Francisco', state: 'CA', country: 'USA', population: 870000},
{name: 'Los Angeles',   state: 'CA', country: 'USA', population: 3970000}

Exemplos de clientes

Web

let results;

results = await execute(db.pipeline().collection("books")
  .where(field("rating").equal(5))
  .where(field("published").lessThan(1900))
);

results = await execute(db.pipeline().collection("books")
  .where(and(field("rating").equal(5), field("published").lessThan(1900)))
);
Swift
var results: Pipeline.Snapshot

results = try await db.pipeline().collection("books")
  .where(Field("rating").equal(5))
  .where(Field("published").lessThan(1900))
  .execute()

results = try await db.pipeline().collection("books")
  .where(Field("rating").equal(5) && Field("published").lessThan(1900))
  .execute()

Kotlin

var results: Task<Pipeline.Snapshot>

results = db.pipeline().collection("books")
    .where(field("rating").equal(5))
    .where(field("published").lessThan(1900))
    .execute()

results = db.pipeline().collection("books")
    .where(Expression.and(field("rating").equal(5),
      field("published").lessThan(1900)))
    .execute()

Java

Task<Pipeline.Snapshot> results;

results = db.pipeline().collection("books")
    .where(field("rating").equal(5))
    .where(field("published").lessThan(1900))
    .execute();

results = db.pipeline().collection("books")
    .where(Expression.and(
        field("rating").equal(5),
        field("published").lessThan(1900)
    ))
    .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import And, Field

results = (
    client.pipeline()
    .collection("books")
    .where(Field.of("rating").equal(5))
    .where(Field.of("published").less_than(1900))
    .execute()
)

results = (
    client.pipeline()
    .collection("books")
    .where(And(Field.of("rating").equal(5), Field.of("published").less_than(1900)))
    .execute()
)
Java
Pipeline.Snapshot results1 =
    firestore
        .pipeline()
        .collection("books")
        .where(field("rating").equal(5))
        .where(field("published").lessThan(1900))
        .execute()
        .get();

Pipeline.Snapshot results2 =
    firestore
        .pipeline()
        .collection("books")
        .where(and(field("rating").equal(5), field("published").lessThan(1900)))
        .execute()
        .get();

Comportamento

Várias etapas

Vários estágios where(...) podem ser encadeados, atuando como uma expressão and(...) em cada condição.

Node.js

const cities = await db.pipeline()
  .collection("/cities")
  .where(field("location.country").equals("USA"))
  .where(field("population").greaterThan(500000))
  .execute();

A filtragem com base em um or lógico de duas condições precisa ser feita como uma única etapa where(...).

Node.js

const cities = await db.pipeline()
  .collection("/cities")
  .where(field("location.state").equals("NY").or(field("location.state").equals("CA")))
  .execute();

Expressões complexas

A condição de filtro pode conter condições complexas com expressões e operadores lógicos profundamente aninhados. Exemplo:

Node.js

const cities = await db.pipeline()
  .collection("/cities")
  .where(
    field("name").like("San%")
    .or(
      field("location.state").charLength().greaterThan(7)
      .and(field("location.country").equals("USA"))))

filtra /cities com base em uma expressão regular ou se a cidade estiver em USA com um nome de estado longo o suficiente. Qualquer expressão pode ser fornecida como condição, mas só vai corresponder às que forem avaliadas como true.

Ordenação de etapas

A ordem das etapas é importante porque pode mudar a ordem de avaliação da consulta. Por exemplo, a consulta:

Node.js

const cities = await db.pipeline()
  .collection("/cities")
  .limit(10)
  .where(field("location.country").equals("USA"))
  .execute();

só vai filtrar location.country para um conjunto (potencialmente aleatório) de 10 documentos, já que a etapa limit(...) anterior restringe os documentos que são fornecidos à etapa where(...). Por isso, a regra geral é colocar as etapas where(...) o mais cedo possível na consulta.

Funcionalidade semelhante ao HAVING:

A etapa where(...) pode vir depois de qualquer etapa que mude o esquema dos documentos, como select(...) ou aggregate(...), e se referirá aos campos produzidos nessas etapas. É importante notar que, para aggregate(...), uma cláusula where(...) que se refere aos campos acumulados funciona como uma cláusula HAVING em um sistema SQL típico. Exemplo:

Node.js

const cities = await db.pipeline()
  .collection("/cities")
  .aggregate({
    accumulators: [field("population").sum().as("total_population")],
    groups: ['location.state']
  })
  .where(field("total_population").greaterThan(10000000))

permite retornar os estados que têm cidades com uma população total maior.