Auswählen

Beschreibung

Generiert neue Dokumente, entweder durch Verweisen auf eine Teilmenge vorhandener Felder oder durch Zuweisen eines Felds zum Ergebnis eines bestimmten Ausdrucks.

Beispiele

Web

const result = await execute(db.pipeline()
  .collection("books")
  .select(field("soldBooks").multiply(field("price")).round().as("partialRevenue"))
  .aggregate(field("partialRevenue").sum().as("totalRevenue"))
  );
Swift
let result = try await db.pipeline()
  .collection("books")
  .select([Field("soldBooks").multiply(Field("price")).round().as("partialRevenue")])
  .aggregate([Field("partialRevenue").sum().as("totalRevenue")])
  .execute()

Kotlin

val result = db.pipeline()
    .collection("books")
    .select(Expression.multiply(field("soldBooks"), field("price")).round().alias("partialRevenue"))
    .aggregate(AggregateFunction.sum("partialRevenue").alias("totalRevenue"))
    .execute()

Java

Task<Pipeline.Snapshot> result = db.pipeline()
    .collection("books")
    .select(Expression.multiply(field("soldBooks"), field("price")).round().alias("partialRevenue"))
    .aggregate(AggregateFunction.sum("partialRevenue").alias("totalRevenue"))
    .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field

result = (
    client.pipeline()
    .collection("books")
    .select(
        Field.of("soldBooks")
        .multiply(Field.of("price"))
        .round()
        .as_("partialRevenue")
    )
    .aggregate(Field.of("partialRevenue").sum().as_("totalRevenue"))
    .execute()
)
Java
Pipeline.Snapshot result =
    firestore
        .pipeline()
        .collection("books")
        .select(round(multiply(field("soldBooks"), field("price"))).as("partialRevenue"))
        .aggregate(sum("partialRevenue").as("totalRevenue"))
        .execute()
        .get();

Verhalten

Position einer Select Stage

Es gibt keine Einschränkungen für die Verwendung einer SELECT-Phase. Allerdings sind alle Felder, die nicht in einer SELECT-Phase enthalten sind, für nachfolgende Phasen in einer Pipeline nicht zugänglich. Wenn Sie beispielsweise nur die Felder name und location aller Städte in Kanada aus dem folgenden Dataset auswählen möchten:

Node.js

await db.collection("cities").doc("SF").set({
  name: "San Francisco",
  population: 800000,
  location: {country: "USA", state: "California"}
});

await db.collection("cities").doc("TO").set({
  name: "Toronto",
  population: 3000000,
  location: {country: "Canada", province: "Ontario"}
});

Die folgende Pipeline kann verwendet werden:

Node.js

const names = await db.pipeline()
  .collection("/cities")
  .where(equal(field("location.country"), "Canada"))
  .select(stringConcat(field("name"), ", ", field("location.country")).as("name"), "population")
  .execute();

Dadurch werden die folgenden Dokumente erstellt:

{ name: "Toronto, Canada", population: 3000000 },

Wenn die Phase select(...) jedoch vor der Phase where(...) platziert wird, z. B. so:

Node.js

const names = await db.pipeline()
  .collection("/cities")
  .select(stringConcat(field("name"), ",", field("location.country")).as("name"), "population")
  .where(equal(field("location.country"), "Canada"))
  .execute();

Es werden keine Dokumente erstellt, da location.country vor der Ausführung der Phase where(...) aus dem Dokument entfernt wurde.

Verschachtelte Felder auswählen

In der Phase select(...) können verschachtelte Felder aus Maps und Arrays ausgewählt werden. Wenn Sie beispielsweise das verschachtelte Feld country und den ersten Eintrag des Arrays landmarks aus den folgenden Dokumenten auswählen möchten:

Node.js

await db.collection("cities").doc("SF").set({
  name: "San Francisco",
  population: 800000,
  location: { country: "USA", state: "California" },
  landmarks: [ "Golden Gate Bridge", "Alcatraz" ]
});

await db.collection("cities").doc("TO").set({
  name: "Toronto",
  population:  3000000,
  province: "ON",
  location: { country: "Canada", province: "Ontario" },
  landmarks: [ "CN Tower", "Casa Loma" ]
});

await db.collection("cities").doc("AT").set({
  name: "Atlantis",
  population: null
});

Die folgende Pipeline kann verwendet werden:

Node.js

const locations = await db.pipeline()
  .collection("/cities")
  .select(
    field("name").as("city"),
    field("location.country").as("country"),
    field("landmarks").offset(0).as("topLandmark"))
  .execute();

Dadurch werden die folgenden Dokumente erstellt:

{ city: "San Francisco", country: "USA", topLandmark: "Golden Gate Bridge" },
{ city: "Toronto", country: "Canada", topLandmark: "CN Tower" },
{ city: "Atlantis" }

Wenn ein verschachtelter Kartenwert oder Arraywert nicht vorhanden ist, wird er nicht in das resultierende Dokument aufgenommen. Der Array- und Kartenzugriff in der SELECT-Phase verhält sich identisch mit den Funktionen offset(...) bzw. get_field(...).

Verschachtelte Felder zuweisen

Das Ergebnis eines Ausdrucks kann auch einem verschachtelten Feld zugewiesen werden. So kann in der Phase select(...) eine Teilmenge verschachtelter Felder aus der vorherigen Phase zurückgegeben werden. Mit dem folgenden Beispiel kann dafür gesorgt werden, dass nur die Informationen city und state zurückgegeben werden, während die ursprüngliche Form des Dokuments beibehalten wird:

Node.js

const results = await db.pipeline()
  .collection("/users")
  .addFields(
    field("__name__"),
    field("address.city").as("address.city"),
    field("address.state").as("address.state"))
  .execute();