Perbedaan antara getSize () dan count () pada koleksi

82

Saya telah mendengar berkali-kali bahwa mereka berdua sama. Tapi saya menghadapi masalah aneh, dalam koleksi produk modul CatalogSearch, count () mengembalikan jumlah produk yang benar sementara getSize () mengembalikan nol.

Jadi, pada dasarnya inilah yang saya dapatkan:

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

Tapi saya ingin getSize () memiliki hitungan yang benar karena memutuskan apakah akan menampilkan pagination dan produk di halaman pencarian atau tidak. Saya menggunakan Inner Join, Left Join dan Where condition hanya dalam koleksi untuk lebih spesifik.

Adakah ide mengapa saya mendapatkan masalah aneh ini?

Terima kasih

MEMPERBARUI:

Pertanyaan saya sebelumnya, Bagaimana cara mengkloning koleksi di Magento? Saya ingin melakukan dua operasi berbeda pada satu koleksi. Koleksi pertama menunjukkan getSize () yang benar, tetapi kemudian jika getSize () adalah nol, saya menghapus klausa WHERE dan memberikan kondisi WHERE baru. Setelah ini, saya mendapatkan SQL mentah yang benar seperti yang saya harapkan, dan menjalankannya di MySQL juga memberikan serangkaian catatan yang benar, tetapi hanya getSize () pada koleksi yang memberikan nol hitungan.

Jadi pada dasarnya saya mungkin perlu memuat ulang koleksi, karena getSize () mengambil hitungan lama. Masuk akal?

MagExt
sumber

Jawaban:

84

Sebagian besar (jika tidak semua) koleksi tersebut diperluas Varien_Data_Collection_Db. Berikut adalah 2 metode dari kelas ini

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

Ada perbedaan. Untuk getSize()koleksi tidak dimuat. Untuk count()itu. Biasanya model pengumpulan menggunakan getSize()metode yang sama seperti di atas dan hanya menimpa getSelectCountSql().
Dalam getSelectCountSql()batas diatur ulang untuk mendapatkan jumlah total catatan yang tersedia untuk filter yang ditetapkan ( wherepernyataan). Lihat cara getSelectCountSql()kerjanya

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;
} 
Marius
sumber
3
Bagus! Jadi apa yang harus menjadi langkah saya selanjutnya untuk memuat ulang koleksi sehingga dapat diperbaiki getSize()? Terima kasih!
MagExt
Sejujurnya saya tidak tahu mengapa Anda mendapatkan hasil ini. Dalam CatalogSearchmodul tidak ada yang menimpa getSize()atau getSelectCountSql(). Ini seharusnya bekerja secara default, kecuali jika Anda menambahkan beberapa kode khusus. Bisakah Anda memposting cara Anda membangun koleksi?
Marius
memperbarui pertanyaan.
MagExt
3
Tidak ada cara untuk mengatur ulang _totalRecords. Anda dapat mencoba mengkloning koleksi sebelum memanggil getSize()koleksi asli. Mungkin itu akan berhasil.
Marius
Anda juga dapat melakukan sesuatu seperti ini untuk mendapatkan hitungan "reset":$sql = $collection->getSelectCountSql(); return $collection->getConnection()->fetchOne($sql);
koosa
14

Hati-hati. Ini benar, tetapi metode ini ditimpa Varien_Data_Collection_Dbseperti yang dijelaskan oleh Marius

Lihat saja

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

Jadi seharusnya level rendah ini sama. Kedua metode memuat koleksi dan menghitung item.

MEMPERBARUI

Oh saya melihat masalah: getSize () cache _totalRecords, ini berarti tidak dihitung ulang. Periksa di mana _totalRecordsdiatur?

Fabian Blechschmidt
sumber
Ya saya telah melihatnya, tetapi tidak bisa mengetahuinya mengapa keduanya menghasilkan jumlah yang berbeda untuk koleksi yang sama? Adakah ide bagaimana memuat ulang koleksi atau sesuatu untuk mendapatkan penghitungan yang benar getSize()?
MagExt
memperbarui entri
Fabian Blechschmidt
1
getSize()tidak memuat koleksi untuk catatan yang berasal dari basis data. Tidak kecuali Anda mengganti metode dan menyuruhnya memuat koleksi.
Marius
_totalRecords dilindungi sehingga tidak dapat menyebutnya di file khusus saya dengan koleksi. echo count($collection->load()->getItems());memberikan hitungan yang benar, tetapi sekali lagi saya ingin getSize()bekerja.
MagExt
5

Jawaban ini muncul di google untuk "magento getSize salah" dan pencarian serupa jadi saya ingin menambahkan skenario yang mungkin berguna bagi seseorang

Ketika Anda memiliki pernyataan grup dalam permintaan Anda dan Anda melakukan

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

Mysql akan mengembalikan hitungan untuk SETIAP grup, jadi Varien_Data_Collection_Db :: getSize () akan mengembalikan jawaban yang salah, ini karena fungsi ini mengambil baris pertama:

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

Saat populasinya

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

Ini memilih baris pertama dan karenanya mengembalikan total dari kelompok pertama sebagai ukuran total.

Saya akhirnya menghasilkan kode ini untuk dihitung, berdasarkan nilai unik atribut dalam permintaan saya.

$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);
changeling
sumber
2

Kalau-kalau Anda berakhir di sini, ada perbaikan sederhana lain untuk dicoba:

System -> Index Management

dan pilih mereka semua (bahkan jika mereka menunjukkan "Hijau, tidak perlu indeks ulang" dan memaksa mereka untuk mengindeks ulang.

Ini menyelesaikan getSize()masalah kosong saya , yang pada gilirannya, memungkinkan permintaan database Khusus dan Baru untuk menemukan produk, memenuhi persyaratan "jika" dan membuat dengan benar.

BVRoc
sumber
0

Ketika count($collection)berbeda dari yang $collection->getSize()saya miliki dengan reindexproduk, maka semuanya bekerja dengan baik.

Zsolti
sumber
-1

Ada perbedaan utama Untuk getSize () koleksi produk tidak dimuat. Untuk count () itu akan memuat seluruh koleksi produk. Jadi untuk katalog besar tidak disarankan menggunakan fungsi hitung dalam koleksi apa pun.

Nayan Baraiya
sumber
Sudah dikatakan di posting Marius ...
sv3n