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