คอลเล็กชันย่อย

คำอธิบาย

subcollection(...)ขั้นตอนการป้อนข้อมูลช่วยให้คุณดำเนินการรวมข้อมูลระหว่างผู้ปกครองกับบุตรหลานได้ง่ายๆ โดยใช้ฟิลด์ __name__ ในตัว

คุณสามารถเชื่อมโยงขั้นตอนเพิ่มเติมกับขั้นตอน subcollection(...) เพื่อทำการกรองหรือรวบรวมเอกสารที่ซ้อนกันได้ โปรดทราบว่าฟิลด์ อ้างอิงที่ใช้ในขั้นตอนต่อๆ ไปจะอ้างอิงเอกสารจากคอลเล็กชันที่ซ้อนกัน ไม่ใช่เอกสารหลัก หากต้องการอ้างอิงฟิลด์ในขอบเขตระดับบน ก่อนอื่นให้ใช้ขั้นตอน let(...) เพื่อกำหนดตัวแปร จากนั้น อ้างอิงตัวแปรเหล่านั้นในขอบเขตภายใน

ตัวอย่าง

Node.js

db.pipeline()
  .collection("/restaurants")
  .add_fields(subcollection("reviews")
    .aggregate(average("rating").as("avg_rating"))
    .toScalarExpression()
    .as("avg_rating"))

พฤติกรรม

ต้องใช้subcollection(...)ในบริบทของ คำสั่งย่อย โดยใช้ __name__ (การอ้างอิงเอกสาร) ของเอกสารปัจจุบัน ในขอบเขตระดับบนเพื่อกำหนดคอลเล็กชันย่อยที่จะดึงข้อมูล เช่น หากเอกสารหลักคือ /restaurants/pizza-place subcollection("reviews") จะแสดงเอกสารทั้งหมดจากคอลเล็กชัน /restaurants/pizza-place/reviews

หากมีการเปลี่ยนชื่อการอ้างอิงเอกสาร หรือกำหนดฟิลด์ด้วย __name__ ไม่ได้ ให้เขียนการรวมด้วยตนเอง เช่น

Node.js

db.pipeline()
  .collection("/restaurants")
  .let(field("__name__").as("restaurant_name"))
  .add_fields(db.pipeline()
    .collectionGroup("reviews")
    .where(field("__name__").parent().equals(variable("restaurant_name")))
    .aggregate(average("rating").as("avg_rating"))
    .toScalarExpression()
    .as("avg_rating"))

ยังคงเป็นไปได้ เนื่องจากโดยพื้นฐานแล้วขั้นตอนนี้เป็นเพียงไวยากรณ์ที่ทำให้เข้าใจง่ายกว่า รูปแบบการรวมที่ซับซ้อนกว่านี้

สำหรับเอกสารต่อไปนี้

Node.js

const restaurant1 = db.collection("restaurants").document("pizza-place");
const restaurant2 = db.collection("restaurants").document("urban-bite");
const restaurant3 = db.collection("restaurants").document("nacho-house");

await restaurant1.create({ name: "Pizza Place" });
await restaurant2.create({ name: "Urban Bite" });
await restaurant3.create({ name: "Nacho House" });

await restaurant1.collection("reviews").doc("1").create({ rating: 5 });
await restaurant1.collection("reviews").doc("1").create({ rating: 2 });

await restaurant2.collection("reviews").doc("1").create({ rating: 3 });
await restaurant2.collection("reviews").doc("1").create({ rating: 4 });
await restaurant2.collection("reviews").doc("1").create({ rating: 5 });

คำค้นหาต่อไปนี้จะดึงข้อมูลร้านอาหารแต่ละร้านและสรุปรีวิวในreview_summaryฟิลด์ใหม่

Node.js

const results = await db.pipeline()
  .collectionGroup("restaurants")
  .add_fields(subcollection("reviews")
    .aggregate(
      countAll().as("review_count"),
      average("rating").as("avg_rating"))
    .asScalarExpression()
    .as("review_summary"))
  .execute();

และให้ผลลัพธ์ต่อไปนี้

{ name: "Pizza Place", review_summary: { review_count: 2, avg_rating: 3.5 } },
{ name: "Urban Bite",  review_summary: { review_count: 3, avg_rating: 4.0 } },
{ name: "Nacho House", review_summary: { review_count: 0, avg_rating: null } },