الوصف
تنشئ هذه العملية مستندات جديدة، إما من خلال الإشارة إلى مجموعة فرعية من الحقول الحالية، أو من خلال تعيين حقل لنتيجة تعبير معيّن.
أمثلة
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();
السلوك
موضع مرحلة الاختيار
لا توجد قيود على وقت استخدام مرحلة اختيارية، ولكن لن تكون أي حقول غير مضمّنة في مرحلة اختيارية متاحة للمراحل اللاحقة في مسار. على سبيل المثال، لاختيار الحقلَين 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(...).
اختيار الحقول المتداخلة
يمكن استخدام المرحلة select(...) لاختيار حقول متداخلة من الخرائط والمصفوفات. على سبيل المثال، لاختيار الحقل 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").offset(0).as("topLandmark"))
.execute();
التي تنتج المستندات التالية:
{ city: "San Francisco", country: "USA", topLandmark: "Golden Gate Bridge" },
{ city: "Toronto", country: "Canada", topLandmark: "CN Tower" },
{ city: "Atlantis" }
إذا لم تكن قيمة الخريطة أو قيمة الصفيف المتداخلة متوفّرة، لن يتم تضمينها في المستند الناتج. يتشابه سلوك الوصول إلى المصفوفة والخريطة في مرحلة الاختيار مع سلوك الدالتَين offset(...) وget_field(...) على التوالي.
تحديد الحقول المتداخلة
يمكن أيضًا تعيين نتيجة تعبير إلى حقل مدمج، ما يتيح للمرحلة select(...) عرض مجموعة فرعية من الحقول المدمجة من المرحلة السابقة. على سبيل المثال، يمكن استخدام ما يلي لضمان عرض معلومات city وstate فقط مع الحفاظ على الشكل الأصلي للمستند:
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();