प्रदर्शन: सभी उत्पादों के प्रकारों की सूची उत्पाद सूची पर इन्वेंटरी स्टॉक स्तर जोड़ें


12

TL, DR , आवश्यकता सूची उत्पाद के एक स्टॉक स्तर को श्रेणी उत्पाद सूची पृष्ठ पर प्रदर्शित करने की है, जो मैगेंटो के ढांचे का पालन करने वाले प्रदर्शन के साथ छोटे अतिरिक्त प्रश्नों / स्मृति के रूप में है।


स्केलेबिलिटी के लिए प्रीलोडिंग पर विनय कोप्प का लेख पढ़ने के बाद ।

प्रदर्शन उत्पाद झीलों के लिए कुछ अतिरिक्त प्रश्नों / भारों के साथ श्रेणी उत्पाद सूची पृष्ठों ( list.phtml ) पर इन्वेंट्री स्टॉक स्तरों को शामिल करने का सबसे अच्छा तरीका क्या है ?

मैं कुछ तरीकों से अवगत हूँ:

afterLoad ()media_gallery अतिरिक्त प्रश्नों के बिना शामिल किए जाने केसाथ अच्छी तरह से काम करता है, हालांकि मैं इन्वेंट्री के साथ एक ही दृष्टिकोण को लागू करने में सफल नहीं रहा हूं।

$attributes = $_product->getTypeInstance(true)->getSetAttributes($_product);
$media_gallery = $attributes['media_gallery'];
$backend = $media_gallery->getBackend();
$backend->afterLoad($_product);

प्रत्यक्ष एसक्यूएलproduct_id उदाहरण के लिए एक कुंजी के साथ संग्रह के समानांतर में आवश्यक डेटा इकट्ठा करने के लिए। लेकिन ढांचे के माध्यम से अधिक साधनों की तलाश है।

वर्तमान में मैं बस के stock_itemमाध्यम से वस्तु लोड कर रहा हूँ :

$_product->load('stock_item')->getTotalQty(); जो काम करता है, लेकिन मैं संग्रह में सभी उत्पादों की इन्वेंट्री स्टॉक कुल प्राप्त करने के लिए और अधिक प्रश्नों को शामिल करता हूं।

...

__EAV_LOAD_MODEL__ (Mage_Catalog_Model_Product, id: stock_item, attributes: NULL)
__EAV_LOAD_MODEL__ (Mage_Catalog_Model_Product, id: stock_item, attributes: NULL)
__EAV_LOAD_MODEL__ (Mage_Catalog_Model_Product, id: stock_item, attributes: NULL)

...

अजीब तरह से, यह काम करता है। जादू Mage_Eav_Model_Entity_Abstract-> लोड ($ ऑब्जेक्ट, $ एंटिटी, $ विशेषताओं) में होता है। यदि $ विशेषताएँ खाली हैं, तो इसे loadAllAttribute ($ ऑब्जेक्ट) कहा जाएगा। इसलिए $ उत्पाद-> लोड ('ब्लाह') 'मीडिया_गैलरी' सहित सभी लापता विशेषताओं को लोड करेगा - विलियम ट्रान Nov 19 '14 4:45 बजे

पहले से लोड किए गए संग्रह में आवश्यक मान जोड़ें।

परत / फ़िल्टर में शीर्ष स्तर के उत्पादन संग्रह में आवश्यक डेटा जोड़ने का स्पष्ट सरल तरीका, सबसे अच्छा तरीका प्रतीत होगा।

मैंने एक ऑब्जर्वर addInventoryDataToCollection () Mage_CatalogInventory_Model_Observer में देखा कि ऐसा लगता है कि यह प्राप्त होगा, लेकिन एक कस्टम मॉड्यूल पर्यवेक्षक के लिए विधि जोड़ना संगत प्रतीत नहीं होता है।

<events>
    <catalog_product_collection_load_after>
        <observers>
            <inventory>
                <class>cataloginventory/observer</class>
                <method>addInventoryDataToCollection</method>
            </inventory>
        </observers>
    </catalog_product_collection_load_after>
</events>

जिसके परिणामस्वरूप:

चेतावनी: लाइन 71 पर foreach () /app/code/core/Mage/CatalogInventory/Model/Resource/Stock/Item/Collection.php पर अमान्य तर्क दिया गया


1
अच्छा प्रश्न बूमर
अमित बेरा

जवाबों:


4

यहाँ असली मुद्दा प्री-लोडिंग नहीं है, यह सटीकता है। उत्पादों के संग्रह के लिए स्टॉक राशि प्राप्त करना अपेक्षाकृत आसान है:

$products = Mage::getModel('catalog/product')->getCollection()
    ->addCategoryFilter($_category);
$stockCollection = Mage::getModel('cataloginventory/stock_item')
    ->getCollection()
    ->addProductsFilter($products);

अब दो प्रश्नों के साथ, आपके पास आवश्यक सभी जानकारी है। वे केवल एक दूसरे से संबंधित होना मुश्किल है, जो एक साहचर्य सरणी का उपयोग करके 'product_id' => 'stock'और एक गेटर लिखकर तय किया जा सकता है । इसके अलावा, AddProductsFilter को अनुकूलित किया जा सकता है:

public function addProductIdsFilter(array $productIds)
{
    if(empty($productIds) {
        $this->_setIsLoaded(true);
    }
    $this->addFieldToFilter('main_table.product_id', array('in' => $productIds));
    return $this;
}

यह आपको टाइप चेक और सरणी क्लोनिंग से बचाता है।

अब समस्या ब्लॉक HTML कैश है। इस श्रेणी के पृष्ठ को तब शुद्ध करने की आवश्यकता होती है जब किसी उत्पाद को उसमें निहित किसी उत्पाद पर अपडेट किया जाता है। जहां तक ​​मुझे पता है, यह मानक नहीं है, क्योंकि केवल स्टॉक की स्थिति बदलने से उत्पाद (या अधिक सटीक, दृश्यता) वाले श्रेणी पृष्ठ का शुद्धिकरण होता है। इसलिए आपको cataloginventory_stock_item_before_saveउस श्रेणी के पेज के लिए कम से कम और शायद कुछ अन्य लोगों और एचटीएमएल कैश (और एफपीसी कैश) का निरीक्षण करना होगा ।


आपका अंतिम बिंदु वह कारण है जो हम स्टॉक डेटा को पुनः प्राप्त करने के लिए अतिरिक्त अनुरोध के लिए गए थे। यदि आपके पास तेज़ गति से चलने वाले उत्पादों की श्रेणियां हैं, तो आप अपना अधिकांश समय फ़्लश / अमान्य होने पर खर्च करेंगे। अगर किसी उत्पाद को उस श्रेणी से हटा दिया जाता है, तो हमें केवल श्रेणी पेज कैश को शुद्ध करने की आवश्यकता होती है। कोई एक जादू समाधान नहीं है जिसे आपको केस के आधार पर किसी मामले में सबसे कुशल कार्यान्वयन करना होगा। यदि आप चाहते हैं कि आप स्टॉक डेटा को कैश कर सकते हैं तो केवल पूरे पृष्ठ के बजाय फ्लश के बाद पुनर्निर्माण करना होगा।
जॉन-जेएच

यदि आप स्टॉक डेटा को उसी तरह लागू करते हैं जो आप अभी करते हैं, तो DOM को अपडेट करने के लिए JavaScript डेटा का उपयोग करके, आप लिख सकते हैं कि ब्लॉक को अपनी कैश कुंजी के साथ उपयोग करना और केवल स्टॉक डेटा को अमान्य करना। यह है कि मैं आपकी स्थिति के लिए यह करूंगा और ईएसआई आधारित एफपीसी का उपयोग नहीं करूंगा, लेकिन एक जो अनुरोध प्रोसेसर में पंच ब्लॉक को छेद सकता है। न केवल राउटर बिट के लिए, बल्कि प्रति पृष्ठ केवल एक php दुभाषिया की आवश्यकता के लिए। जब कोई मशीन किसी भी कारण से दबाव में आती है, तो आपका php दुभाषिया सबसे अधिक Cpu गहन संसाधन है। यह एक अच्छा सप्ताहांत परियोजना की तरह अधिक से अधिक ध्वनि करने के लिए शुरू हो रहा है ;-)
मेल्विन

3
यह सामान का प्रकार है जो काम को वास्तव में दिलचस्प बनाता है जहां आपको कार्यान्वयन और संभावित मुद्दों और बाधाओं के बारे में वास्तव में सोचना पड़ता है। मैं स्पष्ट रूप से देखता हूं कि आप इस समय सिंगल PHP प्रक्रिया से कहां से आ रहे हैं, यह हमारे लिए कोई समस्या नहीं है, लेकिन यह देख सकते हैं कि यह आपके पैमाने पर कैसे प्रभाव डालेगा। पृष्ठ पर प्रदर्शित शेयर मूल्य महत्वपूर्ण कार्यक्षमता नहीं है, इसलिए हम इसे उपयोगकर्ता को प्रभावित किए बिना लोड के बाद एक माध्यमिक संसाधन के रूप में लोड करते हैं। यह उत्पाद सूची पर एक शर्म की बात है एक डिफ़ॉल्ट सुविधा नहीं है।
जॉन-जेएच

1
हाँ, मैं इस विचार के साथ खेल रहा हूँ कि यह रेडिस से सीधे लाया जाए और php को काटे। खुले रेस्टी पर यिचुन झांग द्वारा कुछ वास्तव में दिलचस्प काम है ।
मेल्विन

2

मुझे लगता है कि आपने पहले ही स्वीकार कर लिया है और अब तक कोई संदेह नहीं है, लेकिन मैं यह बताना चाहता हूं कि आप कितने करीब थे, addInventoryDataToCollection()लेकिन ऐसा लगता है कि आपने कॉन्फिग फाइल को गलत तरीके से देखा है या हम बड़े पैमाने पर विभिन्न संस्करणों का उपयोग कर रहे हैं। मेरी एक प्रति के CatalogInventory/etc/config.xmlलिए एक अलग विधि हैcatalog_product_collection_load_after

 <catalog_product_collection_load_after>
    <observers>
        <inventory>
            <class>cataloginventory/observer</class>
            <method>addStockStatusToCollection</method>
        </inventory>
    </observers>
 </catalog_product_collection_load_after>

addInventoryDataToCollection() में कहा जाता है <sales_quote_item_collection_products_after_load>

के लिए स्रोत addStockStatusToCollection()है:

public function addStockStatusToCollection($observer)
{
    $productCollection = $observer->getEvent()->getCollection();
    if ($productCollection->hasFlag('require_stock_items')) {
        Mage::getModel('cataloginventory/stock')->addItemsToProducts($productCollection);
    } else {
        Mage::getModel('cataloginventory/stock_status')->addStockStatusToProducts($productCollection);
    }
    return $this;
}

require_stock_itemsलोड होने से पहले आप या तो संग्रह पर ध्वज सेट कर सकते हैं, श्रेणी सूची के पीछे ब्लॉक के लिए शायद इतना आसान नहीं है, या Mage::getModel('cataloginventory/stock')->addItemsToProducts($productCollection)पहले से लोड होने के बाद आप संग्रह पर मैन्युअल रूप से कॉल कर सकते हैं । addItemsToProducts()आप के लिए सभी StockItems हो जाता है और उन्हें अपने ProductCollection को संलग्न करता है

public function addItemsToProducts($productCollection)
{
    $items = $this->getItemCollection()
        ->addProductsFilter($productCollection)
        ->joinStockStatus($productCollection->getStoreId())
        ->load();
    $stockItems = array();
    foreach ($items as $item) {
        $stockItems[$item->getProductId()] = $item;
    }
    foreach ($productCollection as $product) {
        if (isset($stockItems[$product->getId()])) {
            $stockItems[$product->getId()]->assignProduct($product);
        }
    }
    return $this;
}

1

क्या आप वार्निश या एफपीसी का उपयोग कर रहे हैं या भविष्य में योजना बना रहे हैं?

हमने पाया कि उत्पाद लिस्टिंग पर आवश्यक छेद छेद / ईएसआई अनुरोधों की मात्रा के साथ यह लगभग एक अलग दृष्टिकोण के लिए चुने गए कैशिंग के लायक नहीं था।

हमने एक वेबसाइट पर एक समाधान लागू किया है जो उत्पादों के लिए स्टॉक डेटा पुनर्प्राप्त करने के लिए एक कस्टम नियंत्रक के लिए AJAX अनुरोध का उपयोग करता है और जावास्क्रिप्ट डोम अपडेट को संभालता है। स्टॉक डेटा के लिए अतिरिक्त अनुरोध ~ 100ms जो समग्र (दृश्यमान) पृष्ठ लोड समय पर बिल्कुल भी प्रभाव नहीं डालता है। दंपति जो कि प्राइमेड एफपीसी के साथ पेज रिक्वेस्ट कर रहे हैं, उनके 100 पेज से नीचे के प्रोडक्ट लिस्टिंग पर स्टॉक डेटा दिखाने के लिए कम परफॉर्मेंस ओवरहेड के साथ आपकी एक रैपिड साइट है।

आप सभी को टेम्पलेट वार करने की ज़रूरत है, प्रत्येक उत्पाद आवरण html में productId जोड़ें, ताकि आपकी जावास्क्रिप्ट को पता चले कि प्रत्येक उत्पाद पर कौन सा स्टॉक डेटा लागू होता है।

यदि आप वास्तविक स्टॉक डेटा के लिए अतिरिक्त कैशिंग तकनीकों को देखते हैं, तो आप प्रत्येक अनुरोध पर डेटाबेस को इनिट मेंज / हिट न करके 100 सेंटीमीटर से नीचे गिरा सकते हैं।

क्षमा करें, यदि यह वह नहीं है जो आप ढूंढ रहे हैं, लेकिन हमने इसे अपनी आवश्यकताओं के विरुद्ध मापनीयता और प्रदर्शन के लिए सबसे अच्छा तरीका माना है।


2
अराजकता बंदर को तैनात करें और देखें कि आपके कैश स्टोरेज के गिरने पर क्या होता है। इस प्रश्न में विशेष रूप से कैश पर भरोसा नहीं करने का उल्लेख है। यह इस तरह से उत्तर देता है कि एक ग्राहक को आश्वस्त करने का हमारा काम है कि एफपीसी अपने बिल्ट / मॉम्सबेसमेंट टेम्पलेट को ठीक करने वाला नहीं है।
मेल्विन

आप वास्तव में मेरे उत्तर को गलत समझते हैं यदि आपको लगता है कि मैं प्रदर्शन के लिए और समाधान के रूप में एफपीसी / वार्निश का सुझाव दे रहा हूं। मैंने कहा कि यदि वे एफपीसी / वैनिश का उपयोग कर रहे हैं या विचार कर रहे हैं तो उन्हें छिद्रों / ईएसआई अनुरोधों को कम करने के लिए इस दृष्टिकोण की जांच करनी चाहिए। हम स्टॉक डेटा प्राप्त कर रहे हैं जो हमें कैश को लीवरेज किए बिना 100ms से कम में चाहिए।
जॉन-जेएच

और आपको उसी समय में ईएसआई का उपयोग करके समान डेटा मिलेगा। ईएसआई के साथ आपका दृष्टिकोण मौलिक रूप से अलग है। और इसलिए, बिना किसी कैश के आप अभी भी कम समय में एक ही डेटा प्राप्त कर सकते हैं। JSON भेजने के लिए अभी तक एक और राउटर से गुजरने के बजाय, आप जावास्क्रिप्ट में एक स्टॉक ऐरे लिखते हैं जो DOM आदि को अपडेट करता है, नर्क, इसे JSON में रखें यदि आप चाहते हैं, तो बस राउटर को काट दें।
मेल्विन

1
कैशिंग का उपयोग किया जा रहा है, लेकिन सवाल प्रदर्शन अनुकूलन की रेखाओं के साथ अधिक है। कुछ पृष्ठभूमि: magento.stackexchange.com/questions/13957/… (कोई कैश / शायद ही कोई) उत्तर के लिए धन्यवाद हालांकि, इनपुट की सराहना करते हैं!
B00MER

निश्चित नहीं है कि M2 में ऐसा करने का "सर्वोत्तम अभ्यास" तरीका है, लेकिन आपका समाधान यह है कि हमने हमेशा इसे Magento 1.x.
शाम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.