دَعْ

الوصف

تحديد متغيّرات مؤقتة يمكن الرجوع إليها في المراحل اللاحقة من عملية التنفيذ

لا يتم تضمين المتغيّرات التي تم إنشاؤها في المرحلة let(...) في النتائج النهائية إلا إذا تم تعيينها بشكل صريح لحقل في مرحلة لاحقة (على سبيل المثال، باستخدام add_fields(...) أو select(...)). يتيح لك ذلك تبسيط المنطق المعقّد من خلال تقسيمه إلى مكوّنات أصغر قابلة لإعادة الاستخدام بدون تشويش المستندات الناتجة. تكون مرحلة let(...) مفيدة بشكل خاص لخطوط المعالجة الفرعية المرتبطة، حيث يحتاج خط المعالجة الفرعي إلى الرجوع إلى قيمة من نطاق المستند الرئيسي.

أمثلة

Node.js

const results = await db.pipeline()
  .collection("/awards")
  // `let(...)` referred to as `define(...)` in the Web SDK.
  .define(rand().as("r"))
  .addFields(
    switchOn(
      lessThan(variable("r"), 0.05), constant("rare"),
      lessThan(variable("r"), 0.25), constant("uncommon"),
      constant("common")).as("random_score"))
  .execute();

السلوك

المتغيرات مقابل الحقول

في حين تمثّل الحقول البيانات المخزّنة داخل المستندات، فإنّ المتغيّرات هي قيم مؤقتة لا تكون متاحة إلا أثناء تنفيذ مسار العرض.

الحقول المتغيرات
الغرض الوصول إلى الحقول أو تخزينها في المستندات إنشاء قيم مؤقتة أو الوصول إليها أثناء تنفيذ البنية الأساسية
استخدام حِزمة تطوير البرامج (SDK) field("name") variable("name")
النطاق محلية للمستند الحالي من المستوى العام إلى مسار المبيعات ومسارات المبيعات الفرعية
المراجع غير المحدّدة تُقيَّم إلى absent يؤدي إلى حدوث خطأ أثناء التشغيل

النطاق:

في حين أنّ نطاق الحقول يقتصر على المستند المحلي، يتم تحديد المتغيّرات في نطاق منفصل وتبقى متاحة في جميع المراحل إلى أن يتم دمج عدة مستندات معًا في المرحلة الأولى (مثل aggregate(...) أو distinct(...)). لا تسمح المراحل التي "تدمج" عدة مستندات باستخدام مراجع المتغيّرات بعد ذلك، لأنّه عند دمج نتائج المرحلة السابقة معًا، لن تكون هناك قيمة واحدة للمتغيّر.

الإجراء: الإشارة إلى متغيّر بعد فلترة حقول المستند.

Node.js

const results = db.pipeline()
  .collection("/awards")
  .define(min(field("score").abs(), constant(100)).as("normalized_score"))
  .select(field("__name__"), field("owner_id"))
  // Successfully able to use the variable.
  .where(variable("normalized_score").greaterThan(10))
  .execute();

لا: تشير إلى متغيّر بعد عملية تجميع.

Node.js

const results = db.pipeline()
  .collection("/awards")
  .define(min(field("score").abs(), constant(100)).as("normalized_score"))
  .aggregate({
    accumulators: [ field("score").avg().as("avg_score") ],
    groups: [ field("owner_id") ]
  })
  // Attempting to use the variable throws a request validation error.
  .where(variable("normalized_score").greaterThan(10))
  .execute();

المَراجع غير المحدّدة:

في حين أنّه لا بأس في الإشارة إلى حقل غير محدّد (ويتم تقييمه إلى absent فقط)، ستفشل محاولة الإشارة إلى متغيّر غير محدّد أثناء التحقّق من صحة الطلب. بهذا المعنى، يمكن اعتبار مراجع الحقول على أنّها عمليات بحث في خريطة أثناء وقت التشغيل، بينما تشبه مراجع المتغيرات المتغيرات في لغة برمجة يتم تجميعها بشكل ثابت.

النطاق العام والاستعلامات الفرعية

تُعدّ المتغيرات ضرورية عند العمل مع عمليات نقل البيانات المتداخلة. يتم تنفيذ عملية فرعية ضمن نطاقها الخاص، ولا يمكنها الوصول إلا إلى حقول المستندات التي تتم معالجتها حاليًا. لاستخدام قيمة من المستند "الأصلي" داخل طلب بحث فرعي، يجب أولاً تعريفها كمتغير باستخدام المرحلة let(...).

Node.js

// Fetch reviewers alongside their negative reviews.
const pipeline = db.pipeline()
  .collection("/reviewers")
  // `let(...)` referred to as `define(...)` in the Web SDK.
  .define(field("__name__").as("reviewer_name"))
  .select("__name__", array(db.pipeline().collectionGroup("reviews")
    .where(field("author").equals(variable("reviewer_name")))
    .where(field("rating").lessThan(2))
    .select("review", "rating")).as("negative_reviews"))
  .execute();

المتغيرات المتداخلة

سيؤدي تحديد متغيّر باسم سبق تحديده في مرحلة let(...) سابقة إلى استبدال المتغيّر السابق. يمكن استخدام ذلك لتعديل الحالة المؤقتة أثناء تقدّم عملية المعالجة.

تخضع المتغيرات المُشار إليها في خط الأنابيب الفرعي لقواعد النطاق المعجمي المتّبعة في العديد من لغات البرمجة، وتشير إلى المتغيرات التي تحمل الاسم نفسه والمحدّدة بواسطة خط الأنابيب الأقرب (الأصلي).

المقارنة مع add_fields(...)

تتصرّف المرحلة let(...) بشكل مشابه للمرحلة add_fields(...)، ولكن بدلاً من إضافة حقول إلى المستند، فإنّها تعيّن قيمًا للمتغيرات.