Sự khác biệt giữa getSize () và Count () trên bộ sưu tập


82

Tôi đã nghe nhiều lần rằng cả hai đều giống nhau. Nhưng tôi đang đối mặt với một vấn đề kỳ lạ, trong bộ sưu tập sản phẩm của mô-đun CatalogSearch, Count () đang trả về số lượng sản phẩm chính xác trong khi getSize () đang trả về 0.

Vì vậy, về cơ bản đây là những gì tôi đang nhận được:

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

Nhưng tôi muốn getSize () có số đếm chính xác vì nó quyết định có hiển thị phân trang và sản phẩm trong trang tìm kiếm hay không. Tôi đang sử dụng Nội dung tham gia, Tham gia trái và Điều kiện duy nhất trong bộ sưu tập để cụ thể hơn.

Bất cứ ý tưởng tại sao tôi nhận được vấn đề kỳ lạ này?

Cảm ơn

CẬP NHẬT:

Câu hỏi trước của tôi, Làm thế nào để sao chép bộ sưu tập trong Magento? Tôi muốn thực hiện hai thao tác khác nhau trên một bộ sưu tập. Bộ sưu tập đầu tiên hiển thị đúng getSize (), nhưng sau đó nếu getSize () bằng 0, tôi đã xóa mệnh đề WHERE và đưa ra điều kiện WHERE mới. Sau này, tôi nhận được SQL thô đúng như những gì tôi mong đợi và việc chạy nó trong MySQL cũng cung cấp một bộ hồ sơ chính xác, nhưng chỉ có getSize () trên bộ sưu tập là không có số lượng.

Vì vậy, về cơ bản tôi có thể cần tải lại bộ sưu tập, vì getSize () đang lấy số cũ. Có ý nghĩa?

Câu trả lời:


84

Hầu hết (nếu không phải tất cả) các bộ sưu tập mở rộng Varien_Data_Collection_Db. Dưới đây là 2 phương thức từ lớp này

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

Có một sự khác biệt. Đối với getSize()bộ sưu tập không được tải. Đối với count()nó là. Thông thường các mô hình bộ sưu tập sử dụng getSize()phương pháp tương tự như trên và chỉ ghi đè getSelectCountSql().
Trong getSelectCountSql()giới hạn được đặt lại để có được tổng số bản ghi có sẵn cho các bộ lọc ( wherecâu lệnh) đã đặt. Xem cách làm getSelectCountSql()việc

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
Tuyệt quá! Vì vậy, bước tiếp theo của tôi là gì để tải lại bộ sưu tập để nó có thể được chính xác getSize()? Cảm ơn!
MagExt

Tôi thực sự không biết tại sao bạn nhận được kết quả này. Trong CatalogSearchmô-đun không có gì ghi đè getSize()hoặc getSelectCountSql(). Nó sẽ hoạt động theo mặc định, trừ khi bạn thêm một số mã tùy chỉnh. Bạn có thể đăng cách bạn xây dựng bộ sưu tập?
Marius

cập nhật câu hỏi.
MagExt

3
Không có cách nào để thiết lập lại _totalRecords. Bạn có thể thử sao chép bộ sưu tập trước khi gọi getSize()bộ sưu tập gốc. Có lẽ điều đó sẽ làm việc.
Marius

bạn cũng có thể làm một cái gì đó như thế này để có được số lần "thiết lập lại":$sql = $collection->getSelectCountSql(); return $collection->getConnection()->fetchOne($sql);
koosa

14

Hãy cẩn thận. Điều này là chính xác, nhưng các phương thức được ghi đè lên Varien_Data_Collection_Dbnhư được mô tả bởi Marius

Chỉ cần nhìn vào

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

Vì vậy, nó nên ở mức thấp này là như nhau. Cả hai phương pháp tải bộ sưu tập và đếm các mục.

CẬP NHẬT

Ồ tôi thấy một vấn đề: getSize () lưu trữ _totalRecords, điều này có nghĩa là nó không được tính toán lại. Kiểm tra xem _totalRecordsđược đặt ở đâu?


Có, tôi đã xem xét nó, nhưng không thể hiểu tại sao cả hai đều tạo ra số lượng khác nhau cho cùng một bộ sưu tập? Bất kỳ ý tưởng làm thế nào để tải lại bộ sưu tập hoặc một cái gì đó để có được tính chính xác getSize()?
MagExt

đã cập nhật mục
Fabian Blechschmidt

1
getSize()không tải bộ sưu tập cho các bản ghi xuất phát từ cơ sở dữ liệu. Không trừ khi bạn ghi đè phương thức và yêu cầu nó tải bộ sưu tập.
Marius

_totalRecords được bảo vệ nên không thể gọi nó trong tệp tùy chỉnh của tôi với bộ sưu tập. echo count($collection->load()->getItems());đưa ra số đếm chính xác, nhưng một lần nữa tôi muốn getSize()làm việc.
MagExt

5

Câu trả lời này xuất hiện trên google cho "magento getSize sai" và các tìm kiếm tương tự vì vậy tôi muốn thêm một kịch bản có thể hữu ích cho ai đó

Khi bạn có một tuyên bố nhóm trong truy vấn của bạn và bạn làm một

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

Mysql sẽ trả về số đếm cho MACHI của các nhóm, vì vậy Varien_Data_Collection_Db :: getSize () sẽ trả về câu trả lời sai, điều này là do hàm này tìm nạp hàng đầu tiên:

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

Khi nó cư trú

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

Nó chọn hàng đầu tiên và do đó trả về tổng của nhóm đầu tiên là tổng kích thước.

Tôi đã kết thúc với mã này để đếm, dựa trên các giá trị duy nhất của các thuộc tính trong truy vấn của tôi.

$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

Chỉ trong trường hợp bạn kết thúc ở đây, có một cách khắc phục đơn giản khác để thử:

System -> Index Management

và chọn tất cả chúng (ngay cả khi chúng đang hiển thị "Màu xanh lá cây, không cần chỉ mục lại" và buộc chúng phải liên kết lại.

Điều này đã giải quyết getSize()vấn đề trống rỗng của tôi , từ đó cho phép các yêu cầu cơ sở dữ liệu Đặc biệt và Mới tìm thấy các sản phẩm, đáp ứng các điều kiện "nếu" và hiển thị đúng.


0

Khi count($collection)khác với những sản phẩm $collection->getSize()tôi đã làm reindex, thì mọi thứ đều hoạt động tốt.


-1

Có một sự khác biệt chính Đối với getSize () bộ sưu tập sản phẩm không được tải. Đối với tính () nó sẽ tải toàn bộ bộ sưu tập sản phẩm. Vì vậy, đối với danh mục lớn, không nên sử dụng chức năng đếm trong bất kỳ bộ sưu tập nào.


Đã nói trong bài Marius ...
sv3n
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.