Alt koleksiyon

Açıklama

subcollection(...) giriş aşaması, yerleşik __name__ alanı kullanılarak üst-alt birleştirme işlemlerinin kolayca yapılmasını sağlar.

İç içe yerleştirilmiş dokümanlarda filtreleme veya toplama işlemleri gerçekleştirmek için subcollection(...) aşamasına ek aşamalar eklenebilir. Sonraki aşamalarda kullanılan tüm alan referanslarının, üst doküman yerine iç içe yerleştirilmiş koleksiyondaki dokümanlara referans verdiğini unutmayın. Üst kapsamdaki alanlara başvurmak için önce let(...) aşamasını kullanarak değişkenleri tanımlayın, ardından bu değişkenlere yerel kapsamda referans verin.

Örnekler

Node.js

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

Davranış

subcollection(...) aşaması, bir alt sorgu bağlamında kullanılmalıdır. Hangi alt koleksiyonun getirileceğini belirlemek için üst kapsamdaki mevcut belgenin __name__ (belge referansı) kullanılır. Örneğin, üst belge /restaurants/pizza-place ise subcollection("reviews"), /restaurants/pizza-place/reviews koleksiyonundaki tüm belgeleri döndürür.

Doküman referansı yeniden adlandırılmışsa veya __name__ ile alan tanımlamak mümkün değilse birleştirme işlemini manuel olarak şu şekilde yazın:

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

Bu aşama temelde bu daha karmaşık birleştirme biçimi üzerinde yalnızca söz dizimi kolaylığı sağladığından bu işlem hâlâ mümkündür.

Aşağıdaki dokümanlar için:

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

Aşağıdaki sorgu her restoranı alır ve yorumlarını yeni bir review_summary alanında özetler:

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

ve aşağıdaki sonuçları üretir:

{ 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 } },