ایک Magento ڈویلپر نے 300 الگ الگ ProductRepositoryInterface::getById() کالز کو ایک ہی collection query سے بدل دیا۔ ڈیٹا بیس ہٹس 300 سے کم ہو کر 1 رہ گئیں، اور کیٹیگری پیج نمایاں طور پر تیزی سے لوڈ ہونے لگا۔ اس کا نقصان کیا ہوا؟ اسٹور فرنٹ سے کچھ پروڈکٹس غائب ہو گئے، جس سے خریدار اور مالکان حیران رہ گئے۔
Magento کیٹیگری پیج پر N+1 کا مسئلہ
پیج پر 300 پروڈکٹس کی فہرست تھی۔ ہر پروڈکٹ کے لیے کوڈ نے repository کے getById() میتھڈ کے ذریعے دو custom attributes حاصل کیے، جس سے ہر پروڈکٹ کے لیے ایک query تیار ہوئی—یہ کلاسک N+1 پیٹرن ہے۔ ان پر-پروڈکٹ لوڈز کو ایک collection سے بدلنے سے، جو ایک ہی query میں تمام مطلوبہ rows حاصل کر لیتا ہے، query کی تعداد میں بھاری کمی آئی۔ فرنٹ اینڈ لیٹنسی (latency) میں بہتری آئی، لیکن پروڈکٹ لسٹ میں اب وہ اشیاء غائب تھیں جو پہلے نظر آتی تھیں۔
Collection اسٹاک سے باہر (out-of-stock) اشیاء کو کیوں چھپاتا ہے
Magento کا CatalogInventory ماڈیول فرنٹ اینڈ کے لیے بنائے گئے کسی بھی product collection میں خود بخود "in-stock" فلٹر شامل کر دیتا ہے۔ یہ فلٹر اس وقت فعال ہوتا ہے جب اسٹور کی سیٹنگ Display Out of Stock Products بند ہو، جو کہ ان تاجروں کے لیے ایک عام انتخاب ہے جو دستیاب نہ ہونے والی اشیاء نہیں دکھانا چاہتے۔
اس کے برعکس، repository کبھی بھی اسٹاک فلٹر لاگو نہیں کرتا۔ یہ صرف یہ چیک کرتا ہے کہ پروڈکٹ موجود ہے یا نہیں اور انوینٹری لیول سے قطع نظر اسے واپس کر دیتا ہے۔ جب کوڈ repository کالز سے collection پر منتقل ہوا، تو اسٹاک فلٹر نے خاموشی سے ہر اس پروڈکٹ کو نکال دیا جس کی مقدار (quantity) صفر تھی۔ کوئی ایرر لاگ نہیں ہوا؛ collection نے صرف ڈویلپر کی توقع سے کم rows واپس کیں۔
تاجروں کے لیے اس کے کیا معنی ہیں
ایک اسٹور فرنٹ جو خاموشی سے out-of-stock SKUs کو نکال دیتا ہے، کئی مسائل پیدا کرتا ہے:
- فرنٹ اینڈ کمپوننٹس کو ادھوری انٹریز ملتی ہیں، جس سے خالی لیبلز یا غلط قیمتیں ظاہر ہوتی ہیں۔
- ڈیبگنگ (debugging) مشکل ہو جاتی ہے کیونکہ علامت—یعنی پروڈکٹس کا غائب ہونا—کوئی وارننگ پیدا نہیں کرتی۔
چونکہ زیادہ تر خودکار ٹیسٹ (automated tests) ان-اسٹاک فکسچر (in-stock fixtures) استعمال کرتے ہیں، اس لیے یہ بگ اکثر تب تک چھپا رہتا ہے جب تک سائٹ اصل انوینٹری کے ساتھ نہیں چلتی۔
انوینٹری چھپائے بغیر رفتار کو کیسے برقرار رکھیں
- ڈیفالٹ اسٹاک فلٹر کو چھوڑ دیں – اگر آپ کو دستیابی سے قطع نظر ہر پروڈکٹ کی ضرورت ہے تو collection سے فلٹر کو واضح طور پر ہٹا دیں۔ Magento ہر query کے لیے stock plugin کو غیر فعال کرنے یا تبدیل کرنے کے طریقے فراہم کرتا ہے۔
- جب درستگی اہم ہو تو repository کا استعمال کریں – repository اس بات کی ضمانت دیتا ہے کہ ہر مطلوبہ product ID واپس کی جائے گی، چاہے وہ اسٹاک میں نہ بھی ہو۔ اضافی queries کو قابو کرنے کے لیے نتائج کو کیش (cache) کریں یا صرف وہی IDs لوڈ کریں جن کی آپ کو ضرورت ہے۔
- resource model یا raw SQL کا استعمال کریں – مطلوبہ attributes کے لیے براہ راست product table کو query کریں۔ یہ تمام collection plugins کو نظر انداز کر دیتا ہے اور آپ کو مکمل کنٹرول دیتا ہے کہ کون سی rows شامل کی جائیں گی۔
رفتار بمقابلہ درستگی
ایک شور مچانے والے N+1 لوپ کو ایک ہی collection query سے بدلنا فطری لگتا ہے؛ لیٹنسی (latency) میں کمی محسوس کی جا سکتی ہے۔ تاہم، ایک تیز رفتار query جو پروڈکٹس کا غلط سیٹ واپس کرتی ہے، وہ ایک نقص (defect) ہے، آپٹیمائزیشن (optimization) نہیں۔ ڈویلپرز کو خام رفتار اور نامکمل کیٹلاگ دکھانے کے خطرے کے درمیان توازن برقرار رکھنا چاہیے۔
آگے کیا دیکھنا ہے
- Configuration drift – تصدیق کریں کہ Display Out of Stock Products کا فلیگ کسی بھی کسٹم collection کوڈ کے مطلوبہ طرزِ عمل سے مطابقت رکھتا ہو۔
- Plugin side effects – دوسرے ماڈیولز collections میں اپنے فلٹرز شامل کر سکتے ہیں۔ جب بھی آپ query کی حکمت عملی تبدیل کریں، plugin stack کا جائزہ لیں۔
سبق واضح ہے: collection کے ذریعے N+1 کے مسئلے کو حل کرنا صرف اسی صورت میں فائدہ مند ہے اگر آپ collection کے ڈیفالٹ فلٹرز کا بھی جائزہ لیں۔ Magento کے بلٹ ان اسٹاک فلٹر کو نظر انداز کرنا خاموشی سے آپ کے کیٹلاگ کو کم کر سکتا ہے، جس سے کارکردگی میں اضافہ آمدنی کے نقصان میں بدل سکتا ہے۔
