संग्रह पर getSize () और गणना () के बीच अंतर


81

मैंने कई बार सुना है कि वे दोनों एक ही हैं। लेकिन मैं एक अजीब समस्या का सामना कर रहा हूं, कैटलॉग सर्च मॉड्यूल के उत्पाद संग्रह में, गणना () सही उत्पाद गणना कर रही है जबकि गेटसेज़ () शून्य लौट रहा है।

तो, मूल रूप से यह वही है जो मुझे मिल रहा है:

$collection->count(); //correct count
$collection->getSize(); //0

लेकिन मैं चाहता हूं कि getSize () की सही गिनती हो, क्योंकि यह तय करता है कि सर्च पेज में पेजेशन और प्रोडक्ट्स दिखाना है या नहीं। मैं इनर जॉइन, लेफ्ट जॉइन और जहां केवल विशिष्ट होने के लिए संग्रह में शर्त का उपयोग कर रहा हूं।

किसी भी विचार क्यों मुझे यह अजीब मुद्दा मिल रहा है?

धन्यवाद

अपडेट करें:

मेरा पिछला सवाल, मैगेंटो में संग्रह को कैसे क्लोन किया जाए? मैं एक संग्रह पर दो अलग-अलग ऑपरेशन करना चाहता था। पहला संग्रह सही getSize () दिखाता है, लेकिन फिर अगर getSize () शून्य है, तो मैंने WHERE क्लॉज हटा दिया और नई WHERE शर्त दी। इसके बाद, मुझे सही कच्ची एसक्यूएल मिल रही है जो मुझे उम्मीद थी, और इसे MySQL में चलाने से रिकॉर्ड का एक सही सेट भी मिलता है, लेकिन संग्रह पर केवल getSize () शून्य गणना दे रहा है।

इसलिए मूल रूप से मुझे संग्रह को पुनः लोड करने की आवश्यकता हो सकती है, क्योंकि getSize () पुरानी गिनती ले रहा है। समझ में आता है?

जवाबों:


83

अधिकांश (यदि सभी नहीं हैं) संग्रह का विस्तार होता है Varien_Data_Collection_Db। इस वर्ग के 2 तरीके इस प्रकार हैं

public function getSize()
{
    if (is_null($this->_totalRecords)) {
        $sql = $this->getSelectCountSql();
        $this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams);
    }
    return intval($this->_totalRecords);
} 

public function count() //inherited from Varien_Data_Collection
{
    $this->load();
    return count($this->_items);
}

इसमे अंतर है। के लिए getSize()संग्रह लोड नहीं है। इसके लिए count()है। आमतौर पर संग्रह मॉडल getSize()ऊपर और केवल ओवरराइड के समान विधि का उपयोग करते हैं getSelectCountSql()
में getSelectCountSql()सीमा आदेश सेट फिल्टर (के लिए उपलब्ध अभिलेखों की कुल संख्या प्राप्त करने के लिए रीसेट whereबयान)। देखें कि कैसे getSelectCountSql()काम करता है

public function getSelectCountSql()
{
    $this->_renderFilters();
    $countSelect = clone $this->getSelect();
    $countSelect->reset(Zend_Db_Select::ORDER);
    $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
    $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
    $countSelect->reset(Zend_Db_Select::COLUMNS);
    $countSelect->columns('COUNT(*)');
    return $countSelect;
} 

3
महान! तो संग्रह को फिर से लोड करने के लिए मेरा अगला कदम क्या होना चाहिए ताकि यह सही हो सके getSize()? धन्यवाद!
MagExt

मैं ईमानदारी से नहीं जानता कि आपको यह परिणाम क्यों मिलता है। में CatalogSearchमॉड्यूल कुछ भी नहीं है कि ओवरराइड करता है नहीं है getSize()या getSelectCountSql()। यह डिफ़ॉल्ट रूप से काम करना चाहिए, जब तक कि आपने कुछ कस्टम कोड नहीं जोड़ा। क्या आप संग्रह बनाने के तरीके को पोस्ट कर सकते हैं?
मारियस

प्रश्न को अद्यतन किया।
MagExt

3
रीसेट करने का कोई तरीका नहीं है _totalRecords। आप getSize()मूल संग्रह पर कॉल करने से पहले संग्रह को क्लोन करने का प्रयास कर सकते हैं । शायद वही काम करेगा।
मारियस

आप "रीसेट" गणना प्राप्त करने के लिए कुछ इस तरह से भी कर सकते हैं:$sql = $collection->getSelectCountSql(); return $collection->getConnection()->fetchOne($sql);
koosa

14

सावधान रहे। यह सही है, लेकिन Varien_Data_Collection_Dbमैरियस द्वारा वर्णित तरीकों को अधिलेखित किया गया है

बस एक नज़र है

// \Varien_Data_Collection::getSize
public function getSize()
{
    $this->load();
    if (is_null($this->_totalRecords)) {
        $this->_totalRecords = count($this->getItems());
    }
    return intval($this->_totalRecords);
}

// \Varien_Data_Collection::count
public function count()
{
    $this->load();
    return count($this->_items);
}

तो यह निम्न स्तर पर होना चाहिए। दोनों विधियाँ संग्रह को लोड करती हैं और आइटमों की गणना करती हैं।

अपडेट करें

ओह, मुझे एक समस्या दिखाई देती है: getSize () _totalRecords को कैश करता है, इसका मतलब है कि यह पुनर्गणना नहीं है। जांचें कि कहां _totalRecordsसेट है?


हां मैंने इसे देखा है, लेकिन यह पता नहीं लगा सकता कि दोनों एक ही संग्रह के लिए अलग-अलग मायने क्यों पैदा कर रहे हैं? किसी भी विचार कैसे संग्रह पुनः लोड करने के लिए या सही गिनती में कुछ पाने के लिए getSize()?
MagExt

प्रविष्टि को अपडेट किया गया
फेबियन ब्लेसस्मिड

1
getSize()डेटा बेस से आने वाले रिकॉर्ड के लिए संग्रह को लोड नहीं करता है। जब तक आप विधि को ओवरराइड नहीं करते हैं और इसे संग्रह को लोड करने के लिए कहते हैं।
मारियस

_totalRecords संरक्षित है, इसलिए इसे संग्रह के साथ मेरी कस्टम फ़ाइल में नहीं बुलाया जा सकता है। echo count($collection->load()->getItems());सही गिनती देता है, लेकिन फिर से मैं getSize()काम करना चाहता हूं ।
MagExt

5

यह उत्तर "magento getSize गलत" और इसी तरह की खोजों के लिए Google में दिखाया गया है, इसलिए मैं एक संभावित परिदृश्य जोड़ना चाहूंगा जो किसी के लिए उपयोगी हो सकता है

जब आपकी क्वेरी में एक समूह स्टेटमेंट होता है और आप ए

SELECT COUNT(DISTINCT e.entity_id) ... GROUP BY ( at_id_art.value )

Mysql समूहों में से प्रत्येक के लिए एक गिनती लौटाएगा, इसलिए Varien_Data_Collection_Db :: getSize () गलत उत्तर लौटाएगा, यह इसलिए है क्योंकि यह फ़ंक्शन पहली पंक्ति प्राप्त करता है:

public function getSize()
{
    if (is_null($this->_totalRecords)) {
        $sql = $this->getSelectCountSql();
        $this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams);
    }
    return intval($this->_totalRecords);
}

जब यह आबाद होता है

$this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams);

यह पहली पंक्ति का चयन करता है और इसलिए पहले समूह के कुल आकार के रूप में लौटाता है।

मैंने अपनी क्वेरी में विशेषताओं के अनूठे मूल्यों के आधार पर, इस कोड को गिनने के लिए तैयार किया।

$select = clone $collection->getSelect();
$group = $select->getPart(Zend_Db_Select::GROUP);
$select->reset(Zend_Db_Select::GROUP)->reset(Zend_Db_Select::COLUMNS)->columns("COUNT(DISTINCT {$group[0]})");
$totalCount = $collection->getConnection()->fetchOne($select);

2

बस अगर आप यहाँ समाप्त होते हैं, तो कोशिश करने के लिए एक और सरल समाधान है:

System -> Index Management

और उन सभी का चयन करें (भले ही वे "ग्रीन, नो री-इंडेक्स की आवश्यकता हो" का संकेत दे रहे हों और उन्हें फिर से जोड़ने के लिए मजबूर करें।

इससे मेरी खाली getSize()समस्या हल हो गई , जिसने बदले में, विशेष और नए डेटाबेस अनुरोधों को उत्पादों को खोजने की अनुमति दी, "अगर" शर्तों को पूरा किया और ठीक से प्रस्तुत किया।


0

जब मैं उत्पादों count($collection)से अलग $collection->getSize()था reindex, तब सब कुछ ठीक था।


-1

GetSize के लिए एक मुख्य अंतर है () उत्पाद संग्रह लोड नहीं किया गया है। गिनती के लिए () यह पूरे उत्पाद संग्रह को लोड करेगा। तो बड़े कैटलॉग के लिए किसी भी संग्रह में गिनती फ़ंक्शन का उपयोग करना उचित नहीं है।


पहले से ही मारियस पोस्ट में कहा गया ...
sv3n
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.