Sélectionner

Description

Génère des documents, soit en référençant un sous-ensemble de champs existants, soit en attribuant un champ au résultat d'une expression donnée.

Exemples

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

Comportement

Position d'une étape de sélection

L'utilisation d'une étape de sélection n'est soumise à aucune restriction, mais tous les champs qui ne sont pas inclus dans une étape de sélection ne seront pas accessibles aux étapes suivantes d'un pipeline. Par exemple, pour ne sélectionner que les champs name et location de toutes les villes du Canada dans l'ensemble de données suivant :

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

Le pipeline suivant peut être utilisé :

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

Ce qui produit les documents suivants :

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

Toutefois, si l'étape select(...) est placée avant l'étape where(...), comme suit :

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

Aucun document ne sera produit, car location.country a été supprimé de le document avant l'exécution de l'where(...) étape.

Sélectionner des champs imbriqués

L'étape select(...) peut être utilisée pour sélectionner des champs imbriqués à partir de mappages et de tableaux. Par exemple, pour sélectionner le champ country imbriqué et la première entrée du tableau landmarks à partir des documents suivants :

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

Le pipeline suivant peut être utilisé :

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

Ce qui produit les documents suivants :

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

Si une valeur de mappage ou de tableau imbriquée n'existe pas, elle n'est pas incluse dans le document résultant. L'accès aux tableaux et aux mappages dans l'étape de sélection se comporte de la même manière que les offset(...) et get_field(...) fonctions, respectivement.

Attribuer des champs imbriqués

Le résultat d'une expression peut également être attribué à un champ imbriqué, ce qui permet à l'étape select(...) de renvoyer un sous-ensemble de champs imbriqués de l'étape précédente. Par exemple, le code suivant peut être utilisé pour s'assurer que seules les informations city et state sont renvoyées tout en conservant la forme d'origine du document :

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