선택

설명

기존 필드의 하위 집합을 참조하거나 지정된 표현식의 결과에 필드를 할당하여 새 문서를 생성합니다.

구문

Node.js

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

클라이언트 예시

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()
)
자바
Pipeline.Snapshot result =
    firestore
        .pipeline()
        .collection("books")
        .select(round(multiply(field("soldBooks"), field("price"))).as("partialRevenue"))
        .aggregate(sum("partialRevenue").as("totalRevenue"))
        .execute()
        .get();

동작

선택 단계의 위치

선택 단계의 사용 시기에는 제한이 없지만 선택 단계에 포함되지 않은 필드는 파이프라인의 후속 단계에서 액세스할 수 없습니다.

예를 들어 다음 데이터 세트에서 캐나다의 모든 도시의 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();

where 단계가 실행되기 전에 문서에서 location.country이 삭제되었으므로 문서가 생성되지 않습니다.

중첩 필드 선택

선택 단계는 지도와 배열 모두에서 중첩된 필드를 선택하는 데 사용할 수 있습니다.

예를 들어 다음 문서에서 중첩된 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'}

중첩된 맵 값이나 배열 값이 없으면 결과 문서에 포함되지 않습니다. 선택 단계의 배열 및 맵 액세스는 각각 array_getmap_get 함수와 동일하게 동작합니다.