সাবকোয়েরিগুলির সাথে জয়েন সম্পাদন করুন

সংক্ষিপ্ত বিবরণ

ফায়ারস্টোর এন্টারপ্রাইজ সংস্করণ কোরিলেটেড সাবকোয়েরির মাধ্যমে রিলেশনাল-স্টাইলের জয়েন সমর্থন করে। অনেক NoSQL ডেটাবেসের মতো নয়, যেগুলোতে প্রায়শই ডেটা ডিনরমালাইজ করা বা একাধিক ক্লায়েন্ট-সাইড অনুরোধ সম্পাদন করার প্রয়োজন হয়, সাবকোয়েরি আপনাকে সরাসরি সার্ভারে সম্পর্কিত কালেকশন বা সাবকালেকশন থেকে ডেটা একত্রিত ও অ্যাগ্রিগেট করার সুযোগ দেয়।

সাবকোয়েরি হলো এমন এক্সপ্রেশন যা বাইরের কোয়েরি দ্বারা প্রক্রিয়াকৃত প্রতিটি ডকুমেন্টের জন্য একটি নেস্টেড পাইপলাইন সম্পাদন করে। এটি জটিল ডেটা পুনরুদ্ধার প্যাটার্ন সক্ষম করে, যেমন একটি ডকুমেন্টকে তার সম্পর্কিত সাবকালেকশন আইটেমগুলোর সাথে একত্রে আনা অথবা ভিন্ন ভিন্ন রুট কালেকশনের মধ্যে যৌক্তিকভাবে সংযুক্ত ডেটা যুক্ত করা।

ধারণা

এই অংশে পাইপলাইন অপারেশনে জয়েন সম্পাদনের জন্য সাবকোয়েরি ব্যবহারের মূল ধারণাগুলো তুলে ধরা হয়েছে।

এক্সপ্রেশন হিসেবে সাবকোয়েরি

সাবকোয়েরি কোনো শীর্ষ-স্তরের পর্যায় নয়; বরং এটি একটি এক্সপ্রেশন যা এক্সপ্রেশন গ্রহণকারী যেকোনো পর্যায়ে ব্যবহার করা যায়, যেমন select(...) , add_fields(...) , where(...) , বা sort(...)

Cloud Firestore তিন ধরনের সাবকোয়েরি সমর্থন করে:

  • অ্যারে সাবকোয়েরি: সাবকোয়েরির সম্পূর্ণ ফলাফল সেটকে ডকুমেন্টের একটি অ্যারে হিসেবে বাস্তবায়ন করুন।
  • স্কেলার সাবকোয়েরি: একটি একক মানে মূল্যায়ন করে, যেমন গণনা, গড়, বা সম্পর্কিত কোনো ডকুমেন্টের একটি নির্দিষ্ট ফিল্ড।
  • subcollection(...) সাবকোয়েরি: এক-থেকে-অনেক প্যারেন্ট-চাইল্ড সম্পর্কের জন্য সরলীকৃত জয়েন।

পরিধি এবং ভেরিয়েবল

একটি জয়েন লেখার সময়, নেস্টেড সাবকোয়েরিকে প্রায়শই "বাইরের" ডকুমেন্ট (প্যারেন্ট) থেকে ফিল্ড রেফারেন্স করার প্রয়োজন হয়। এই স্কোপগুলোর মধ্যে সংযোগ স্থাপন করতে, আপনি let(...) পর্যায়টি (কিছু SDK-তে যা define(...) নামে পরিচিত) ব্যবহার করে প্যারেন্ট স্কোপে ভ্যারিয়েবল সংজ্ঞায়িত করেন, যেগুলোকে পরবর্তীতে variable(...) ফাংশন ব্যবহার করে সাবকোয়েরিতে রেফারেন্স করা যায়।

সিনট্যাক্স

নিম্নলিখিত বিভাগগুলিতে জয়েন করার সিনট্যাক্স সম্পর্কে একটি সংক্ষিপ্ত বিবরণ দেওয়া হয়েছে।

let(...) পর্যায়

let(...) পর্যায়টি (কিছু SDK-তে যা define(...) নামে পরিচিত) একটি নন-ফিল্টারিং পর্যায়, যা পরবর্তী নেস্টেড স্কোপগুলোতে ব্যবহারের জন্য প্যারেন্ট স্কোপ থেকে ডেটাকে একটি নামযুক্ত ভেরিয়েবলে সুস্পষ্টভাবে নিয়ে আসে।

অ্যারে সাবকোয়েরি

অ্যারে সাবকোয়েরি হলো এক্সপ্রেশন সাবকোয়েরির একটি বিশেষ রূপ, যা সাবকোয়েরির সম্পূর্ণ ফলাফল সেটকে একটি অ্যারেতে রূপান্তর করে। যদি সাবকোয়েরিটি শূন্যটি সারি ফেরত দেয়, তবে এটি একটি খালি অ্যারেতে রূপান্তরিত হয়। এটি কখনোই একটি null অ্যারে ফেরত দেয় না। এই ধরনের কোয়েরিগুলো তখন উপযোগী হয় যখন চূড়ান্ত ফলাফলে সম্পূর্ণ ফলাফলের প্রয়োজন হয়, যেমন কোনো নেস্টেড বা কোরিলেটেড কালেকশনকে রূপান্তর করার ক্ষেত্রে।

কোয়েরির খরচ কমাতে, ফেচ ও রিটার্ন করা ডেটার পরিমাণও হ্রাস করার জন্য সাবকোয়েরিতে ফিল্টার, সর্ট এবং অ্যাগ্রিগেট করা যায়। সাবকোয়েরির ক্রমকে সম্মান করা হয়, অর্থাৎ সাবকোয়েরির মধ্যে থাকা sort(...) ধাপটি চূড়ান্ত অ্যারেতে ফলাফলের ক্রম নিয়ন্ত্রণ করে।

একটি কোয়েরিকে অ্যারেতে রূপান্তর করতে toArrayExpression() SDK র‍্যাপারটি ব্যবহার করুন।

স্কেলার সাবকোয়েরি

স্কেলার সাবকোয়েরি প্রায়শই select(...) বা where(...) পর্যায়ে ব্যবহৃত হয়, কারণ এটি সম্পূর্ণ কোয়েরিটিকে সরাসরি ম্যাটেরিয়ালাইজ না করেই সাবকোয়েরির ফলাফল ফিল্টার বা বের করার সুযোগ দেয়।

একটি স্কেলার সাবকোয়েরি যা শূন্য ফলাফল দেয়, তা নিজেই null হিসেবে ইভ্যালুয়েট হবে, অন্যদিকে একটি সাবকোয়েরি যা একাধিক উপাদানে ইভ্যালুয়েট হয়, তার ফলে একটি রানটাইম এরর দেখা দেবে।

যখন একটি স্কেলার সাবকোয়েরি প্রতি-ফলাফলে শুধুমাত্র একটি ফিল্ড তৈরি করে, তখন সেই ফিল্ডটিকে সাবকোয়েরিটির শীর্ষ-স্তরের ফলাফল হিসেবে উন্নীত করা হয়। এটি সাধারণত তখন দেখা যায় যখন সাবকোয়েরিটি select(field("user_name")) বা aggregate(countAll().as("total")) দিয়ে শেষ হয়, যেখানে সাবকোয়েরিটির স্কিমাটি কেবল একটি একক ফিল্ড। অন্যথায়, যখন একটি সাবকোয়েরি একাধিক ফিল্ড তৈরি করতে পারে, তখন সেগুলোকে একটি ম্যাপের মধ্যে রাখা হয়।

একটি কোয়েরিকে স্কেলার এক্সপ্রেশনে রূপান্তর করতে toScalarExpression() SDK র‍্যাপারটি ব্যবহার করুন।

subcollection(...) উপ-কোয়েরি

একটি স্টেজ হিসেবে উপলব্ধ হলেও, subcollection(...) ইনপুট স্টেজটি Cloud Firestore হায়ারারকিক্যাল ডেটা মডেলের উপর জয়েন অপারেশন করার সুযোগ দেয়। একটি হায়ারারকিক্যাল মডেলে, কোয়েরিগুলোর প্রায়শই একটি ডকুমেন্টের পাশাপাশি তার নিজস্ব সাব-কালেকশনগুলো থেকেও ডেটা পুনরুদ্ধার করার প্রয়োজন হয়। যদিও আপনি collection_group(...) ইনপুট স্টেজ ব্যবহার করে এবং তারপরে প্যারেন্ট রেফারেন্সের উপর ফিল্টার প্রয়োগ করে এটি করতে পারেন, subcollection(...) অনেক বেশি সংক্ষিপ্ত সিনট্যাক্স প্রদান করে।

অন্তর্নিহিত জয়েন শর্তটি ছাড়া, এটি একটি অ্যারে সাবকোয়েরির মতোই কাজ করে এবং কোনো ডকুমেন্ট মেলানো না গেলে একটি খালি ফলাফল ফেরত দেয়, এমনকি যদি নেস্টেড কালেকশনটির অস্তিত্ব না-ও থাকে।

এটি মূলত একটি সিনট্যাকটিক সুগার : এটি শ্রেণিবদ্ধ সম্পর্কটি সমাধান করার জন্য স্বয়ংক্রিয়ভাবে বাইরের স্কোপে থাকা ডকুমেন্টের __name__ জয়েন কী হিসেবে ব্যবহার করে। এই কারণে, প্যারেন্ট-চাইল্ড সম্পর্কে সংযুক্ত কালেকশনগুলোর মধ্যে লুকআপ করার জন্য এটিই সবচেয়ে পছন্দের উপায়।

উদাহরণ

উদাহরণ ডেটা

নিম্নলিখিতটি পরবর্তী সমস্ত উদাহরণে ব্যবহারের জন্য এক সেট পরীক্ষার ডেটা লোড করে।

নোড.জেএস

// Load set of cities.
const cities = collection(db, "cities");

await setDoc(doc(cities, "SF"), {
  name: "San Francisco",
  state: "CA",
  country: "USA",
});
await setDoc(doc(cities, "LA"), {
  name: "Los Angeles",
  state: "CA",
  country: "USA"
});
await setDoc(doc(cities, "DC"), {
  name: "Washington, D.C.",
  state: null,
  country: "USA"
});
await setDoc(doc(cities, "TOK"), {
  name: "Tokyo",
  state: null,
  country: "Japan"
});

// Load restaurants in various cities.
const sfRestaurants = collection(db, "cities", "SF", "restaurants");
const laRestaurants = collection(db, "cities", "LA", "restaurants");
const dcRestaurants = collection(db, "cities", "DC", "restaurants");

const rest1 = await addDoc(sfRestaurants, {
  name: "Golden Gate Pizza",
  type: "pizza",
  owner_id: "Mario Rossi"
});
const rest2 = await addDoc(sfRestaurants, {
  name: "Bay Area Burger",
  type: "burger",
  owner_id: "Sarah Jenkins"
});
const rest3 = await addDoc(sfRestaurants, {
  name: "Sunset Taco",
  type: "mexican",
  owner_id: "Edward"
});

const rest4 = await addDoc(laRestaurants, {
  name: "Hollywood Sushi",
  type: "sushi",
  owner_id: "Ken Kenji"
});
const rest5 = await addDoc(laRestaurants, {
  name: "Venice Pizza",
  type: "pizza",
  owner_id: "Luigi Romano"
});

const rest6 = await addDoc(dcRestaurants, {
  name: "Capitol Tacos",
  type: "mexican",
  owner_id: "Maria Garcia"
});
const rest7 = await addDoc(dcRestaurants, {
  name: "Georgetown Coffee",
  type: "cafe",
  owner_id: "David Kim"
});

// Load collection of reviews.
const reviews = collection(db, "reviews");

await addDoc(reviews, { restaurant: rest1, rating: 5, reviewer_id "Alice" });
await addDoc(reviews, { restaurant: rest1, rating: 4, reviewer_id "Bob" });
await addDoc(reviews, { restaurant: rest2, rating: 4, reviewer_id "Charlie" });
await addDoc(reviews, { restaurant: rest3, rating: 5, reviewer_id "Diana" });
await addDoc(reviews, { restaurant: rest3, rating: 4, reviewer_id "Edward" });
await addDoc(reviews, { restaurant: rest3, rating: 4, reviewer_id "Fiona" });
// rest4 has 0 reviews
await addDoc(reviews, { restaurant: rest5, rating: 3, reviewer_id "George" });
await addDoc(reviews, { restaurant: rest6, rating: 5, reviewer_id "Hannah" });
await addDoc(reviews, { restaurant: rest6, rating: 4, reviewer_id "Ian" });
await addDoc(reviews, { restaurant: rest7, rating: 5, reviewer_id "Julia" });

অন্য সংগ্রহে একটি নথি সন্ধান করুন

reviews কালেকশন গ্রুপের উপর নিম্নলিখিত কোয়েরিটি একটি প্রাইমারি কী রেফারেন্স ব্যবহার করে restaurant কালেকশন গ্রুপে একটি লুকআপ সম্পাদন করে।

নোড.জেএস

let results = await execute(db.pipeline()
  .collectionGroup("reviews")
  .define(field("restaurant").as("restaurant_name"))
  .addFields(db.pipeline()
    .collectionGroup("restaurant")
    .where(field("__name__").equal(variable("restaurant_name")))
    .select("name", "type")
    .toScalarExpression()
    .as("restaurant")));

প্রতিক্রিয়া

{
  rating: 5,
  reviewer_id "Alice",
  restaurant: { name: "Golden Gate Pizza", type: "pizza" }
},
{
  rating: 4,
  reviewer_id "Bob",
  restaurant: { name: "Golden Gate Pizza", type: "pizza" }
},
{
  rating: 4,
  reviewer_id "Charlie",
  restaurant: { name: "Bay Area Burger", type: "burger" }
},
{
  rating: 5,
  reviewer_id "Diana",
  restaurant: { name: "Sunset Taco", type: "mexican" }
},
{
  rating: 4,
  reviewer_id "Edward",
  restaurant: { name: "Sunset Taco", type: "mexican" }
},
{
  rating: 4,
  reviewer_id "Fiona",
  restaurant: { name: "Sunset Taco", type: "mexican" }
},
{
  rating: 3,
  reviewer_id "George",
  restaurant: { name: "Venice Pizza", type: "pizza" }
},
{
  rating: 5,
  reviewer_id "Hannah",
  restaurant: { name: "Capitol Tacos", type: "mexican" }
},
{
  rating: 4,
  reviewer_id "Ian",
  restaurant: { name: "Capitol Tacos", type: "mexican" }
},
{
  rating: 5,
  reviewer_id "Julia",
  restaurant: { name: "Georgetown Coffee", type: "cafe" }
}

একাধিক সংগ্রহ একত্রিত করুন

নিম্নলিখিত কোয়েরিটি restaurants কালেকশন গ্রুপ থেকে সমস্ত পিজ্জার দোকান খুঁজে বের করে এবং একটি অ্যারে সাবকোয়েরি ব্যবহার করে তাদের সংশ্লিষ্ট রিভিউগুলো সংগ্রহ করে সরাসরি রেসপন্সে যুক্ত করে দেয়।

নোড.জেএস

let results = await execute(db.pipeline()
  .collectionGroup("restaurants")
  .where(field("type").equal("pizza"))
  .define(field("__name__").as("restaurant_name"))
  .select(
    field("name"),
    db.pipeline()
      .collectionGroup("reviews")
      .where(field("restaurant").equal(variable("restaurant_name")))
      .select("rating", "reviewer_id")
      .toArrayExpression()
      .as("reviews")));

প্রতিক্রিয়া

{
  name: "Golden Gate Pizza",
  reviews: [
    { rating: 5, reviewer_id "Alice" },
    { rating: 4, reviewer_id "Bob" }
  ]
},
{
  name: "Venice Pizza",
  type: "pizza",
  owner_id: "Luigi Romano",
  reviews: [
    { rating: 3, reviewer_id "George" }
  ]
}

একাধিক সংগ্রহ জুড়ে একত্রিত করুন

restaurants কালেকশন গ্রুপের উপর করা নিম্নলিখিত কোয়েরিটি, reviews কালেকশন গ্রুপ থেকে প্রতিটি রেস্তোরাঁর গড় রেটিং পাওয়ার জন্য একটি কোরিলেটেড সাবকোয়েরি ব্যবহার করে।

নোড.জেএস

let results = await execute(db.pipeline()
  .collectionGroup("restaurants")
  .where(field("type").equal("pizza"))
  .define(field("__name__").as("restaurant_name"))
  .select(
    field("name"),
    db.pipeline()
      .collectionGroup("reviews")
      .where(field("restaurant").equal(variable("restaurant_name")))
      .aggregate(average("rating").as("avg_rating"))
      .toScalarExpression()
      .as("avg_rating")));

প্রতিক্রিয়া

{
  name: "Golden Gate Pizza",
  avg_rating: 4.5
},
{
  name: "Venice Pizza",
  avg_rating: 3.0
}

প্রতি গ্রুপে শীর্ষ-N (সীমা সহ সাবকোয়েরি)

নিম্নলিখিত কোয়েরিটি restaurants কালেকশন গ্রুপ থেকে সমস্ত ডকুমেন্ট ফেচ করে এবং প্রতিটি রেস্টুরেন্টের জন্য শীর্ষ ২টি সর্বোচ্চ রেটিং প্রাপ্ত রিভিউ ফেচ করতে একটি কোরিলেটেড সাবকোয়েরি ব্যবহার করে।

এটি নিশ্চিত করে যে রিভিউগুলির অ্যারে অতিরিক্ত বড় হয়ে কোয়েরির মেমরি সীমাতে পৌঁছে না যায়।

নোড.জেএস

let results = await execute(db.pipeline()
  .collectionGroup("restaurants")
  .define(field("__name__").as("restaurant_name"))
  .select(
    field("name"),
    db.pipeline()
      .collectionGroup("reviews")
      .where(field("restaurant").equal(variable("restaurant_name")))
      .sort(field("rating").descending())
      .limit(2)
      .select("rating", "reviewer_id")
      .toArrayExpression()
      .as("top_reviews")));

প্রতিক্রিয়া

{
  name: "Golden Gate Pizza",
  top_reviews: [
    { rating: 5, reviewer_id "Alice" },
    { rating: 4, reviewer_id "Bob" }
  ]
},
{
  name: "Bay Area Burger",
  top_reviews: [
    { rating: 4, reviewer_id "Charlie" }
  ]
},
{
  name: "Sunset Taco",
  top_reviews: [
    { rating: 5, reviewer_id "Diana" },
    { rating: 4, reviewer_id "Edward" }
  ]
},
{
  name: "Hollywood Sushi",
  top_reviews: []
},
{
  name: "Venice Pizza",
  top_reviews: [
    { rating: 3, reviewer_id "George" }
  ]
},
{
  name: "Capitol Tacos",
  top_reviews: [
    { rating: 5, reviewer_id "Hannah" },
    { rating: 4, reviewer_id "Ian" }
  ]
},
{
  name: "Georgetown Coffee",
  top_reviews: [
    { rating: 5, reviewer_id "Julia" }
  ]
}

উপ-সংগ্রহে যোগ দিন

নিম্নলিখিত কোয়েরিটি cities কালেকশনটি স্ক্যান করে এবং subcollection(...) পর্যায়টি ব্যবহার করে একটি নেস্টেড কালেকশনের ডকুমেন্টগুলোর সাথে ইমপ্লিসিটলি জয়েন করার মাধ্যমে প্রতি শহরে রেস্তোরাঁর সংখ্যা খুঁজে বের করে।

নোড.জেএস

let results = await execute(db.pipeline()
  .collection("cities")
  .addFields(subcollection("restaurants")
    .toArrayExpression()
    .length()
    .as("restaurant_count")));

প্রতিক্রিয়া

{
  __name__: cities/SF,
  name: "San Francisco",
  state: "CA",
  country: "USA",
  restaurant_count: 3
},
{
  __name__: cities/LA,
  name: "Los Angeles",
  state: "CA",
  country: "USA",
  restaurant_count: 2
},
{
  __name__: cities/DC,
  name: "Washington, D.C.",
  state: null,
  country: "USA",
  restaurant_count: 2
},
{
  __name__: cities/TOK,
  name: "Tokyo",
  state: null,
  country: "Japan",
  restaurant_count: 0
}

একাধিক যোগদানের শর্তাবলী প্রকাশ করুন

নিম্নলিখিত কোয়েরিটি restaurants কালেকশন গ্রুপ স্ক্যান করে এবং নিজেদের রেস্তোরাঁর রিভিউ প্রদানকারী মালিকদের খুঁজে বের করার জন্য reviews কালেকশন গ্রুপের সাথে একটি মাল্টি-ফিল্ড জয়েন সম্পাদন করে।

নোড.জেএস

let results = await execute(db.pipeline()
  .collectionGroup("restaurants")
  .define(field("owner_id"), field("__name__"))
  .where(db.pipeline()
    .collectionGroup("reviews")
    .where(field("restaurant").equal(variable("__name__")))
    .where(field("author").equal(variable("owner_id")))
    .aggregate(count().as("c"))
    .toScalarExpression()
    .greaterThan(0)));

প্রতিক্রিয়া

{
  __name__: cities/SF/restaurants/X9An0HIlx29A9GPuRthS,
  name: "Sunset Taco",
  type: "mexican",
  owner_id: "Edward"
}

যোগদান-বিরোধী ( NOT EXISTS )

নিম্নলিখিত কোয়েরিটি restaurants কালেকশন গ্রুপ স্ক্যান করে সেইসব রেস্তোরাঁ খুঁজে বের করে যেগুলোর এখনও কোনো রিভিউ নেই।

নোড.জেএস

let results = await execute(db.pipeline()
  .collectionGroup("restaurants")
  .define(field("__name__").as("restaurant_name"))
  .where(db.pipeline()
    .collectionGroup("reviews")
    .where(field("restaurant").equal(variable("restaurant_name")))
    .aggregate(count().as("review_count"))
    .toScalarExpression()
    .equal(0)));

প্রতিক্রিয়া

{
  __name__: "cities/LA/restaurants/X9An0HIlx29A9GPuRthS",
  name: "Hollywood Sushi",
  type: "sushi",
  owner_id: "Ken Kenji"
}

সাবকোয়েরি অ্যাজ জয়েন

নিম্নলিখিত কোয়েরিটি প্রতিটি পিজ্জার দোকান এবং তার রিভিউগুলির মধ্যেকার সম্পর্ককে সমতল করে। সাবকোয়েরিটিকে একটি unnest(...) স্টেজের ভিতরে রাখার মাধ্যমে, সার্ভার প্রতিটি মিলে যাওয়া রিভিউর জন্য বাইরের রেস্তোরাঁর ডকুমেন্টটির প্রতিলিপি তৈরি করে, যার ফলে সমতল, সংযুক্ত ডকুমেন্ট তৈরি হয় (যা একটি SQL INNER JOIN অনুরূপ)।

নোড.জেএস

let results = await execute(db.pipeline()
  .collectionGroup("restaurants")
  .where(field("type").equal("pizza"))
  .define(field("__name__").as("restaurant_name"))
  .unnest(
    db.pipeline()
      .collectionGroup("reviews")
      .where(field("restaurant").equal(variable("restaurant_name")))
      .select("rating", "reviewer_id")
      .toArrayExpression()
      .as("review")));

প্রতিক্রিয়া

{
  __name__: "cities/SF/restaurants/xU4pu8nFpnJDPZOwcSPP",
  name: "Golden Gate Pizza",
  type: "pizza",
  owner_id: "Mario Rossi"
  review: { rating: 5, reviewer_id "Alice" }
},
{
  __name__: "cities/SF/restaurants/xU4pu8nFpnJDPZOwcSPP",
  name: "Golden Gate Pizza",
  type: "pizza",
  owner_id: "Mario Rossi",
  review: { rating: 4, reviewer_id "Bob" }
},
{
  __name__: "cities/LA/restaurants/6CYntvNgbYzgaW652Gq1",
  name: "Venice Pizza",
  type: "pizza",
  owner_id: "Luigi Romano",
  review: { rating: 3, reviewer_id "George" }
}

ফিল্টার হিসাবে সম্পর্কহীন সাবকোয়েরি

reviews কালেকশনের উপর নিম্নলিখিত কোয়েরিটি গড় রেটিং-এর চেয়ে বেশি রেটিংযুক্ত রিভিউগুলো খুঁজে বের করার জন্য নিজের উপরই একটি সম্পর্কহীন সাবকোয়েরি ব্যবহার করে ফিল্টার প্রয়োগ করে।

নোড.জেএস

let results = await execute(db.pipeline()
  .collection("reviews")
  // Average review rating is 4.3
  .where(field("rating").greaterThan(db.pipeline()
    .collection("reviews")
    .aggregate(average("rating").as("avg"))
    .toScalarExpression())))
  .select("rating", "reviewer_id");

প্রতিক্রিয়া

{
  rating: 5,
  reviewer_id "Alice"
},
{
  rating: 5,
  reviewer_id "Diana"
},
{
  rating: 5,
  reviewer_id "Hannah"
},
{
  rating: 5,
  reviewer_id "Julia"
}

সর্বোত্তম অনুশীলন

  • toArrayExpression() দিয়ে মেমরি পরিচালনা করুন: toArrayExpression() সাবকোয়েরি ব্যবহারের ক্ষেত্রে সতর্ক থাকুন, কারণ বিপুল সংখ্যক ডকুমেন্ট ম্যাটেরিয়ালাইজ করতে গেলে কোয়েরির মেমরি লিমিট (১২৮ MiB) শেষ হয়ে যেতে পারে। এটি এড়ানোর জন্য, সাবকোয়েরির মধ্যে select(...) ব্যবহার করে শুধুমাত্র প্রয়োজনীয় ফিল্ডগুলো রিটার্ন করুন এবং রিটার্ন করা ডকুমেন্টের সংখ্যা সীমিত করতে where(...) ফিল্টার প্রয়োগ করুন। প্রয়োজন হলে, সাবকোয়েরি দ্বারা রিটার্ন করা ডকুমেন্টের সংখ্যা সর্বোচ্চ করতে limit(...) ব্যবহার করার কথা বিবেচনা করতে পারেন।
  • ইনডেক্সিং: নিশ্চিত করুন যে একটি সাবকোয়েরির where(...) ক্লজে ব্যবহৃত ফিল্ডগুলো ইনডেক্স করা আছে। পারফরম্যান্ট জয়েনগুলো সম্পূর্ণ টেবিল স্ক্যানের পরিবর্তে ইনডেক্স সিক সম্পাদন করার ক্ষমতার উপর নির্ভর করে।

কোয়েরি সংক্রান্ত আরও সেরা অনুশীলন জানতে, আমাদের কোয়েরি অপ্টিমাইজেশন বিষয়ক নির্দেশিকাটি দেখুন।

সীমাবদ্ধতা

  • subcollection(...) এর পরিধি: subcollection(...) ইনপুট পর্যায়টি শুধুমাত্র সাবকোয়েরির মধ্যেই সমর্থিত, কারণ শ্রেণিবদ্ধ সম্পর্ক নির্ণয় এবং জয়েন সম্পাদনের জন্য এটির একটি প্যারেন্ট ডকুমেন্টের প্রেক্ষাপট প্রয়োজন হয়।
  • নেস্টিং গভীরতা: সাবকোয়েরি সর্বোচ্চ ২০ স্তর পর্যন্ত নেস্ট করা যেতে পারে।
  • মেমরি ব্যবহার: ম্যাটেরিয়ালাইজড ডেটার উপর প্রযোজ্য ১২৮ MiB সীমাটি সমস্ত জয়েন করা ডকুমেন্ট সহ সম্পূর্ণ কোয়েরি জুড়ে কার্যকর।