Where

Descripción

Filtra los documentos de la etapa anterior y devuelve solo aquellos en los que la condición se evalúa como true.

Sintaxis:

where(condition: Expr)

Ejemplo

Crea una colección cities con los siguientes 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});

Realiza una búsqueda de igualdad:

Node.js

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

Genera el siguiente resultado:

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

Ejemplos 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();

Comportamiento

Varias etapas

Se pueden encadenar varias etapas de where(...), que actúan como una expresión and(...) en cada condición.

Node.js

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

Sin embargo, el filtrado basado en un or lógico de dos condiciones debe realizarse como una sola etapa where(...).

Node.js

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

Expresiones complejas

La condición de filtro puede contener condiciones de filtro complejas con expresiones y operadores lógicos anidados de forma profunda. Por ejemplo:

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 según una expresión regular o si la ciudad se encuentra en USA con un nombre de estado lo suficientemente largo. Se puede proporcionar cualquier expresión como condición, pero solo coincidirá con aquellas que se evalúen como true.

Orden de las etapas

El orden de las etapas es importante, ya que puede cambiar el orden de evaluación de la consulta. Por ejemplo, la siguiente consulta:

Node.js

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

solo se filtrará en location.country para un conjunto (potencialmente aleatorio) de 10 documentos, ya que la etapa previa limit(...) restringe los documentos que se proporcionan a la etapa where(...). Teniendo esto en cuenta, la regla general es colocar las etapas where(...) lo antes posible en la consulta.

Funcionalidad similar a HAVING:

La etapa where(...) puede aparecer después de cualquier etapa que cambie el esquema de los documentos, como select(...) o aggregate(...), y hará referencia a los campos que se producen en esas etapas. Es importante destacar que, para aggregate(...), una cláusula where(...) posterior que hace referencia a los campos acumulados actúa como una cláusula HAVING en un sistema SQL típico. Por ejemplo:

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 devolver los estados que tienen ciudades con una población total determinada.