Mô tả
Tạo tài liệu mới bằng cách tham chiếu đến một tập hợp con của các trường hiện có hoặc bằng cách gán một trường cho kết quả của một biểu thức nhất định.
Ví dụ
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();
Hành vi
Vị trí của giai đoạn chọn
Không có hạn chế về thời điểm có thể sử dụng giai đoạn chọn, nhưng mọi trường không có trong giai đoạn chọn sẽ không thể truy cập được vào các giai đoạn tiếp theo trong quy trình. Ví dụ: để chỉ chọn các trường name và location của tất cả các thành phố ở Canada trong tập dữ liệu sau:
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"}
});
Bạn có thể sử dụng quy trình sau:
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();
Quy trình này sẽ tạo ra các tài liệu sau:
{ name: "Toronto, Canada", population: 3000000 },
Tuy nhiên, nếu giai đoạn select(...) được đặt trước giai đoạn
where(...), như sau:
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();
Sẽ không có tài liệu nào được tạo vì location.country đã bị xoá khỏi
tài liệu trước khi thực thi giai đoạn where(...).
Chọn các trường lồng nhau
Bạn có thể sử dụng giai đoạn select(...) để chọn các trường lồng nhau từ cả bản đồ và mảng. Ví dụ: để chọn trường country lồng nhau và mục nhập đầu tiên của mảng landmarks trong các tài liệu sau:
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
});
Bạn có thể sử dụng quy trình sau:
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();
Quy trình này sẽ tạo ra các tài liệu sau:
{ city: "San Francisco", country: "USA", topLandmark: "Golden Gate Bridge" },
{ city: "Toronto", country: "Canada", topLandmark: "CN Tower" },
{ city: "Atlantis" }
Nếu không có giá trị bản đồ lồng nhau hoặc giá trị mảng, thì giá trị đó sẽ không được đưa vào tài liệu kết quả. Quyền truy cập vào mảng và bản đồ trong giai đoạn chọn hoạt động giống hệt
như các offset(...) và get_field(...) hàm,
tương ứng.
Gán các trường lồng nhau
Kết quả của một biểu thức cũng có thể được gán cho một trường lồng nhau, giúp bạn có thể trả về một tập hợp con của các trường lồng nhau từ giai đoạn trước.select(...) Ví dụ: bạn có thể sử dụng nội dung sau để đảm bảo chỉ trả về thông tin city và state trong khi vẫn giữ nguyên hình dạng ban đầu của tài liệu:
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();