دَعْ

الوصف

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

لا يتم تضمين المتغيّرات التي تم إنشاؤها في مرحلة 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(...)، ولكن بدلاً من إضافة حقول إلى المستند، فإنّها تعيّن قيمًا للمتغيّرات.