컬렉션에서 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.