Seleziona

Descrizione

Genera nuovi documenti facendo riferimento a un sottoinsieme di campi esistenti o assegnando un campo al risultato di una determinata espressione.

Esempi

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

Comportamento

Posizione di una fase selezionata

Non esistono limitazioni all'utilizzo di una fase di selezione, ma i campi non inclusi in una fase di selezione non saranno accessibili alle fasi successive di una pipeline. Ad esempio, per selezionare solo i campi name e location di tutte le città del Canada dal seguente set di dati:

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

È possibile utilizzare la seguente pipeline:

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

che produce i seguenti documenti:

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

Tuttavia, se la fase select(...) viene posizionata prima della fase where(...), ad esempio:

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

Non verranno prodotti documenti perché location.country è stato rimosso dal documento prima dell'esecuzione della fase where(...).

Seleziona campi nidificati

Lo stage select(...) può essere utilizzato per selezionare i campi nidificati sia dalle mappe sia dagli array. Ad esempio, per selezionare il campo nidificato country e la prima voce dell'array landmarks dai seguenti documenti:

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

È possibile utilizzare la seguente pipeline:

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

che produce i seguenti documenti:

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

Se un valore di mappa o un valore di array nidificato non esiste, non viene incluso nel documento risultante. L'accesso ad array e mappe nella fase di selezione si comporta in modo identico alle funzioni offset(...) e get_field(...), rispettivamente.

Assegnare campi nidificati

Il risultato di un'espressione può essere assegnato anche a un campo nidificato, consentendo alla fase select(...) di restituire un sottoinsieme di campi nidificati dalla fase precedente. Ad esempio, quanto segue può essere utilizzato per garantire che vengano restituite solo le informazioni city e state, preservando al contempo la forma originale del documento:

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