Koleksiyonda getSize () ve count () arasındaki fark


81

Her ikisinin de aynı olduğunu defalarca duydum. Ancak tuhaf bir sorunla karşı karşıyayım, CatalogSearch modülünün ürün koleksiyonunda, getSize () sıfırı döndürürken count () doğru ürün sayısını döndürüyor.

Yani, temelde bu ne alıyorum:

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

Ancak getSize () 'in, sayfalarda sayfalandırma ve sayfa gösterip göstermemeye karar verirken doğru sayıma sahip olmasını istiyorum. Koleksiyonda yalnızca daha belirgin olması için İç Birleştirme, Sol Birleştirme ve Nerede koşulu kullanıyorum.

Neden bu garip sorunu alıyorum herhangi bir fikrin var mı?

Teşekkürler

GÜNCELLEME:

Önceki sorum, Magento'daki koleksiyon nasıl kopyalanır? Bir koleksiyonda iki farklı işlem yapmak istedim. İlk koleksiyon doğru getSize () gösterir, ancak daha sonra getSize () sıfırsa, WHERE yan tümcesini kaldırdım ve yeni WHERE koşulu verdim. Bundan sonra beklediğimden doğru ham SQL alıyorum ve MySQL'de çalıştırmak da doğru bir kayıt kümesi veriyor, ancak koleksiyondaki sadece getSize () sıfır sayım veriyor.

Bu yüzden temelde, getSize () eski sayımı aldığından koleksiyonu yeniden yüklemem gerekebilir. Mantıklı?

Yanıtlar:


83

Koleksiyonların çoğu (hepsi değilse) genişler Varien_Data_Collection_Db. İşte bu sınıftan 2 yöntem

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);
}

Bir fark var. For getSize()koleksiyonu yüklü değil. İçin count()öyle. Genellikle toplama modelleri getSize()yukarıdakiyle aynı yöntemi kullanır ve yalnızca geçersiz kılınır getSelectCountSql().
Gelen getSelectCountSql()sınırı seti filtreleri (mevcut kayıtların toplam sayısını elde etmek için sıfırlanır wheredeyim). Nasıl getSelectCountSql()çalıştığını görün

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
Harika! Öyleyse koleksiyonu yeniden yükleyebilmem için bir sonraki adım ne olmalı getSize()? Teşekkürler!
MagExt

Açıkçası neden bu sonucu aldın bilmiyorum. In CatalogSearchmodülü geçersiz kılar şey yok getSize()ya getSelectCountSql(). Bazı özel kodlar eklemediğiniz sürece varsayılan olarak çalışmalıdır. Koleksiyonu oluşturma şeklinizi gönderebilir misiniz?
Marius

soruyu güncelledi.
MagExt

3
Sıfırlamanın yolu yok _totalRecords. getSize()Orijinal koleksiyonu aramadan önce koleksiyonu klonlamayı deneyebilirsiniz . Belki bu işe yarar.
Marius

ayrıca bir "sıfırlama" sayımı elde etmek için böyle bir şey yapabilirsiniz:$sql = $collection->getSelectCountSql(); return $collection->getConnection()->fetchOne($sql);
koosa

14

Dikkatli ol. Bu doğru, ancak Varien_Data_Collection_DbMarius'un açıkladığı gibi yöntemlerin üzerine yazılmıştır.

Sadece bir göz atın

// \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);
}

Bu yüzden bu düşük seviyede aynı olmalıdır. Her iki yöntem de koleksiyonu yükler ve öğeleri sayar.

GÜNCELLEME

Oh bir sorun görüyorum: getSize () _totalRecords'ı önbelleğe alır, bu yeniden hesaplanmadığı anlamına gelir. Nerede _totalRecordsayarlanmış kontrol edin ?


Evet, baktım ama neden her ikisinin de aynı koleksiyon için farklı sayılar ürettiğini çözemiyorum? Koleksiyonun nasıl yeniden yükleneceğine ya da doğru sayımı alacağınıza dair bir fikriniz var getSize()mı?
MagExt

giriş güncellendi
Fabian Blechschmidt

1
getSize()Veri tabanından gelen kayıtlar için koleksiyonu yüklemez. Yöntemi geçersiz kılmadığınız ve koleksiyonu yüklemesini söylemediğiniz sürece.
Marius

_totalRecords korumalıdır, bu yüzden koleksiyonlu özel dosyamda arayamazsınız. echo count($collection->load()->getItems());doğru sayım veriyor ama yine getSize()çalışmak istiyorum .
MagExt

5

Bu cevap, "magento getSize yanlış" ve benzeri aramalar için google'da görünüyor, bu yüzden birileri için faydalı olabilecek olası bir senaryo eklemek istiyorum

Sorgunuzda bir grup ifadesi varsa ve bir

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

Mysql, grupların EACH'i için bir sayım döndürür, böylece Varien_Data_Collection_Db :: getSize () yanlış cevap döndürür, çünkü bu fonksiyon ilk satırı alır:

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

Dolduğu zaman

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

İlk satırı seçer ve bu nedenle ilk grubun toplamını toplam boyut olarak döndürür.

Sorgudaki özniteliklerin benzersiz değerlerini temel alarak saymak için bu kodla geldim.

$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

Buraya gelmen durumunda, denenecek başka basit bir düzeltme var:

System -> Index Management

ve hepsini seçin ("Yeşil, yeniden indekslemeye gerek yok" belirtilmiş olsalar bile) ve onları yeniden indekslemeye zorlarlar.

Bu benim boş getSize()sorunumu çözdü, bu da Özel ve Yeni veri tabanı taleplerinin ürünleri bulmalarını, "if" koşullarını yerine getirmelerini ve uygun şekilde oluşturmalarını sağladı.


0

Ne zaman count($collection)farklıydı $collection->getSize()ben gerekiyordu reindexürünler, daha sonra her şey iyi çalıştı.


-1

Ana fark var getSize () için ürün koleksiyonu yüklenmedi. Count () için bütün ürün koleksiyonunu yükler. Bu yüzden büyük katalog için herhangi bir koleksiyonda count işlevini kullanmanız önerilmez.


Zaten Marius postasında dedi ...
sv3n
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.