说明
通过引用现有字段的子集,或将某字段设为给定表达式的结果来生成新文档。
语法
Node.js
const names = await db.pipeline()
.collection("/cities")
.select(stringConcat(field("name"), ", ", field("location.country")).as("name"), "population")
.execute();
行为
选择阶段的位置
选择阶段的使用时机不受限制;但凡未在该阶段中包含的字段,流水线的后续阶段将无法访问。
例如,如需从以下数据集中仅选择加拿大所有城市的 name 和 location 字段,请执行以下操作:
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'}});
可使用以下流水线:
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();
将生成以下文档:
{name: 'Toronto, Canada', population: 3000000},
不过,如果 select 阶段放在 where 阶段之前,如下所示:
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();
在执行 location.country 阶段之前,where 已从文档中被移除,因此不会生成任何文档。
选择嵌套字段
选择阶段可用于从 map 和数组中选择嵌套字段。
例如,如需从以下文档中选择嵌套的 country 字段以及 landmarks 数组的首个条目,可按如下方式操作:
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});
可使用以下流水线:
Node.js
const locations = await db.pipeline()
.collection("/cities")
.select(field("name").as("city"), field("location.country").as("country"), field("landmarks").arrayGet(0).as("topLandmark"))
.execute();
将生成以下文档:
{city: 'San Francisco', country: 'USA', topLandmark: 'Golden Gate Bridge'},
{city: 'Toronto', country: 'Canada', topLandmark: 'CN Tower'},
{city: 'Atlantis'}
如果嵌套的 map 值或数组值不存在,则不会出现在生成的文档中。选择阶段对数组与 map 的访问方式,分别与 array_get 和 map_get 函数的行为一致。
更多示例
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() )