选择

说明

通过引用现有字段的子集,或将某字段设为给定表达式的结果来生成新文档。

语法

Node.js

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

行为

选择阶段的位置

选择阶段的使用时机不受限制;但凡未在该阶段中包含的字段,流水线的后续阶段将无法访问。

例如,如需从以下数据集中仅选择加拿大所有城市的 namelocation 字段,请执行以下操作:

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