컬렉션에서 getSize ()와 count ()의 차이점


81

나는 둘 다 동일하다는 것을 여러 번 들었습니다. 그러나 카탈로그 검색 모듈의 제품 컬렉션에서 이상한 문제가 발생했습니다. getSize ()가 0을 반환하는 동안 count ()가 올바른 제품 수를 반환합니다.

따라서 기본적으로 이것은 내가 얻는 것입니다.

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

그러나 검색 페이지에 페이지 매김 및 제품을 표시할지 여부를 결정함에 따라 getSize ()가 올바른 수를 갖기를 원합니다. 컬렉션에서 Inner Join, Left Join 및 Where 조건을보다 구체적으로 사용하고 있습니다.

이 이상한 문제가 발생하는 이유는 무엇입니까?

감사

최신 정보:

내 이전 질문, Magento에서 컬렉션을 복제하는 방법? 한 컬렉션에서 두 가지 다른 작업을 수행하고 싶었습니다. 첫 번째 컬렉션에는 올바른 getSize ()가 표시되지만 getSize ()가 0이면 WHERE 절을 제거하고 새로운 WHERE 조건을 부여했습니다. 이 후, 나는 예상대로 정확한 원시 SQL을 얻었고 MySQL에서 실행하면 올바른 레코드 세트가 제공되지만 컬렉션의 getSize () 만 카운트를 제공하지 않습니다.

따라서 기본적으로 getSize ()가 오래 걸리므로 컬렉션을 다시로드해야 할 수도 있습니다. 맞는 말이다?

답변:


83

대부분의 경우 컬렉션이 확장 Varien_Data_Collection_Db됩니다. 이 클래스의 두 가지 방법은 다음과 같습니다.

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(). 사용자 정의 코드를 추가하지 않으면 기본적으로 작동합니다. 컬렉션을 만드는 방법을 게시 할 수 있습니까?
Marius

질문을 업데이트했습니다.
MagExt

3
재설정 할 방법이 없습니다 _totalRecords. getSize()원본 컬렉션을 호출하기 전에 컬렉션을 복제 할 수 있습니다 . 어쩌면 그것은 효과가있을 것입니다.
Marius

"재설정"카운트를 얻기 위해 이와 같은 작업을 수행 할 수도 있습니다.$sql = $collection->getSelectCountSql(); return $collection->getConnection()->fetchOne($sql);
koosa

14

조심해. 이것은 정확하지만 Varien_Data_Collection_DbMarius가 설명한대로 메서드를 덮어 씁니다.

그냥 살펴봐

// \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

항목을 업데이트
Fabian Blechschmidt

1
getSize()데이터베이스에서 가져온 레코드에 대한 콜렉션을로드하지 않습니다. 메소드를 대체하고 콜렉션을로드하도록 지시하지 않는 한 아닙니다.
Marius

_totalRecords가 보호되어 있으므로 콜렉션이있는 사용자 정의 파일에서 호출 할 수 없습니다. echo count($collection->load()->getItems());정확한 수를 제공하지만 다시 getSize()일하고 싶습니다 .
MagExt

5

이 답변은 Google에 "magento getSize wrong"및 유사한 검색어에 대해 표시되므로 누군가에게 유용한 가능한 시나리오를 추가하고 싶습니다

검색어에 그룹 명세서가 있고

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()문제가 해결 되어 Special 및 New 데이터베이스 요청으로 제품을 찾고 "if"조건을 충족시키고 올바르게 렌더링 할 수있었습니다.


0

count($collection)와는 다른이었다 $collection->getSize()I가 있었다 reindex제품, 다음 다 잘했다.


-1

getSize ()의 주요 차이점은 제품 콜렉션이로드되지 않은 것입니다. count ()의 경우 전체 제품 컬렉션을로드합니다. 따라서 큰 카탈로그의 경우 모든 콜렉션에 count 함수를 사용하지 않는 것이 좋습니다.


이미 마리우스 포스트에서 말했다 ...
sv3n
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.