Wybierz

Opis

Generuje nowe dokumenty, odwołując się do podzbioru istniejących pól lub przypisując pole do wyniku danego wyrażenia.

Przykłady

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

Zachowanie

Położenie etapu wyboru

Nie ma ograniczeń co do tego, kiedy można użyć wybranego etapu, ale żadne pola nieuwzględnione na wybranym etapie nie będą dostępne na kolejnych etapach potoku. Aby na przykład wybrać tylko pola namelocation wszystkich miast w Kanadzie z tego zbioru danych:

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

Możesz użyć tego potoku:

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

W wyniku tego powstają te dokumenty:

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

Jeśli jednak etap select(...) zostanie umieszczony przed etapem where(...), np. w ten sposób:

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

Nie zostaną wygenerowane żadne dokumenty, ponieważ location.country został usunięty z dokumentu przed wykonaniem etapu where(...).

Wybieranie zagnieżdżonych pól

Etap select(...) może służyć do wybierania zagnieżdżonych pól z map i tablic. Na przykład aby wybrać zagnieżdżone pole country i pierwszy wpis z tablicy landmarks z tych dokumentów:

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

Możesz użyć tego potoku:

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

W wyniku tego powstają te dokumenty:

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

Jeśli zagnieżdżona wartość mapy lub wartość tablicy nie istnieje, nie jest uwzględniana w wynikowym dokumencie. Dostęp do tablic i map w fazie wyboru działa identycznie jak funkcje offset(...)get_field(...).

Przypisywanie pól zagnieżdżonych

Wynik wyrażenia można też przypisać do zagnieżdżonego pola, dzięki czemu etap select(...) może zwracać podzbiór zagnieżdżonych pól z poprzedniego etapu. Aby na przykład mieć pewność, że zwracane są tylko informacje citystate, przy jednoczesnym zachowaniu pierwotnego kształtu dokumentu, możesz użyć tego kodu:

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