Gdzie

Opis

Filtruje dokumenty z poprzedniego etapu, zwracając tylko te, w których warunek ma wartość true.

Przykłady

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();
Go
results1, err := client.Pipeline().
	Collection("books").
	Where(firestore.FieldOf("rating").Equal(5)).
	Where(firestore.FieldOf("published").LessThan(1900)).
	Execute(ctx).Results().GetAll()
if err != nil {
	fmt.Fprintf(w, "GetAll failed: %v", err)
	return err
}

results2, err := client.Pipeline().
	Collection("books").
	Where(firestore.And(
		firestore.FieldOf("rating").Equal(5),
		firestore.FieldOf("published").LessThan(1900),
	)).
	Execute(ctx).Results().GetAll()
if err != nil {
	fmt.Fprintf(w, "GetAll failed: %v", err)
	return err
}

Zachowanie

Wiele etapów

Można połączyć ze sobą kilka etapów where(...), które będą działać jak wyrażenie and(...) w przypadku każdego warunku.

Node.js

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

Filtrowanie na podstawie logicznego operatora or dwóch warunków musi być jednak wykonywane jako pojedynczy etap where(...).

Node.js

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

Złożone wyrażenia

Warunek filtra może zawierać złożone warunki filtra z głęboko zagnieżdżonymi wyrażeniami i operatorami logicznymi. Przykład:

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"))))

filtruje /cities na podstawie wyrażenia regularnego lub jeśli miasto znajduje się w USA i ma wystarczająco długą nazwę stanu. Jako warunek można podać dowolne wyrażenie, ale będzie ono pasować tylko do tych, które mają wartość true.

Kolejność etapów

Kolejność etapów jest ważna, ponieważ może zmienić kolejność oceny zapytania. Na przykład zapytanie:

Node.js

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

będzie filtrować tylko location.country w przypadku (potencjalnie losowego) zbioru 10 dokumentów, ponieważ poprzedni etap limit(...) ogranicza dokumenty, które są kiedykolwiek przekazywane do etapu where(...). W związku z tym zaleca się umieszczanie etapów where(...) jak najwcześniej w zapytaniu.

Funkcja podobna do HAVING:

Etap where(...) może występować po dowolnym etapie, który zmienia schemat dokumentów, np. select(...) lub aggregate(...), i będzie odnosić się do pól utworzonych na tych etapach. Ważne jest, że w przypadku aggregate(...) następująca klauzulawhere(...) która odnosi się do zgromadzonych pól, działa jak klauzulaHAVING w typowym systemie SQL. Przykład:

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))

umożliwia zwracanie stanów, w których znajdują się miasta o łącznej liczbie mieszkańców przekraczającej określoną wartość.