Pregunta

He escuchado muchas veces que los dos son lo mismo. Pero estoy frente a un problema raro, en la colección de productos de módulo de CatalogSearch, count () devuelve el recuento correcto del producto, mientras que getSize () devuelve cero.

Así que, básicamente, esto es lo que quiero decir:

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

Pero quiero que el getSize () para tener recuento correcto ya que decide si desea mostrar la paginación y productos en la página de búsqueda o no. Estoy usando combinación interna, Ingreso izquierda y dónde condición única de la colección Para ser más específicos.

Cualquier idea por qué estoy recibiendo este problema raro?

Gracias

ACTUALIZACIÓN:

Mi pregunta anterior, Cómo clonar la colección en Magento? que quería realizar dos operaciones diferentes en una sola colección. La primera muestra correcta recaudación getSize (), pero entonces si el getSize () es cero, I eliminan la cláusula WHERE y dieron nueva condición WHERE. Después de esto, yo estoy recibiendo correcta SQL prima lo que esperaba, y ejecutarlo en MySQL también da un conjunto de registros correcto, pero sólo getSize () en la colección está dando cuenta cero.

Así que básicamente puede tener que recargar la colección, como getSize () está teniendo recuento de edad. Tiene sentido?

¿Fue útil?

Solución

Most (if not all) the collections extend Varien_Data_Collection_Db. Here are the 2 methods from this class

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

There is a difference. For getSize() the collection is not loaded. For count() it is. Usually collection models use the same getSize() method as above and only override getSelectCountSql().
In getSelectCountSql() the limit is reset in order to get the total number of records available for the set filters (where statement). See how the getSelectCountSql() works

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

Otros consejos

Be careful. This is correct, but the methods are overwritten in Varien_Data_Collection_Db as described by Marius

Just have a look into

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

So it should on this low level be the same. Both methods load the collection and count the items.

UPDATE

Oh I see a problem: getSize() caches the _totalRecords, this means it is not recalculated. Check where _totalRecords is set?

This answer shows up in google for "magento getSize wrong" and similar searches so I would like to add a possible scenario that might be useful to someone

When you have a group statement in your query and you do a

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

Mysql will return a count for EACH of the groups, so Varien_Data_Collection_Db::getSize() will return the wrong answer, this is because this function fetches the first row:

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

When it populates

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

It selects the first row and therefore returns the total of the first group as the total size.

I ended up coming up with this code to count, based on the unique values of the attributes in my query.

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

Just in case you end up here, there is another simple fix to try:

System -> Index Management

and select them all (even if they are indicating "Green, no re-index needed" and force them to reindex.

This solved my empty getSize() problem, which in turn, allowed the Special and New database requests to find the products, fulfill the "if" conditions and properly render.

When count($collection) was different than $collection->getSize() I had to reindex the products, then everything worked fine.

There is a main difference For getSize() the product collection is not loaded. For count() it will load whole product collection. So for big catalog it is not advisable to use count function in any collection.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top