A maneira mais eficiente de obter todos os IDs de uma coleção

37

No passado, para obter todos os IDs de uma coleção de produtos, eu sempre os utilizava getAllIds, acreditando que esse era um método que impedia o carregamento completo da coleção com dados, etc.

Mas, na verdade, olhei para o método hoje e ele carrega a coleção e itera sobre cada item para obter a matriz de ID.

public function getAllIds()
{
    $ids = array();
    foreach ($this->getItems() as $item) {
        $ids[] = $this->_getItemId($item);
    }
    return $ids;
}

Minha pergunta é: qual é o método mais eficiente para recuperar apenas o campo ID de uma coleção?

Marty Wallace
fonte

Respostas:

43

Na verdade, getAllIdsé a melhor maneira de fazê-lo. Por exemplo, no modelo de recursos da coleção de produtos, o método se parece com o seguinte:

public function getAllIds($limit = null, $offset = null)
{
    $idsSelect = $this->_getClearSelect();
    $idsSelect->columns('e.' . $this->getEntity()->getIdFieldName());
    $idsSelect->limit($limit, $offset);
    $idsSelect->resetJoinLeft();

    return $this->getConnection()->fetchCol($idsSelect, $this->_bindParams);
}

Portanto, tudo é recuperado de uma única seleção e nenhuma iteração é necessária. Também no modelo de recursos abstratos, fica assim:

public function getAllIds()
{
    $idsSelect = clone $this->getSelect();
    $idsSelect->reset(Zend_Db_Select::ORDER);
    $idsSelect->reset(Zend_Db_Select::LIMIT_COUNT);
    $idsSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
    $idsSelect->reset(Zend_Db_Select::COLUMNS);

    $idsSelect->columns($this->getResource()->getIdFieldName(), 'main_table');
    return $this->getConnection()->fetchCol($idsSelect);
}

Portanto, tudo o que se estende Mage_Core_Model_Resource_Db_Collection_Abstractdeve usar isso, a menos que seja especificado o contrário.

O método que você analisou é da classe base, Varien_Data_Collectionmas é substituído em seus filhos.

Marius
fonte
6

Nesse caso, você pode usar o objeto de coleção

$collection = Mage::getModel('catalog/product')->getCollection()
   ->addAttributeToSelect('entity_id');

[...] 
do your loop
[...]

addAttributeToSelectpois isso entity_idnão é realmente necessário, mas para fins de demonstração, eu o adiciono, adicione os campos necessários e pronto!

Mais sobre coleções que você encontrará nesta Wikipédia

Sander Mangel
fonte
3

Mais otimizado

$collection = Mage::getModel('catalog/product')->getCollection();
$collection->getSelect()->reset(Zend_Db_Select::COLUMNS);
$collection->getSelect()->columns('entity_id');
$collection1Ids[] = $collection->getAllIds();
Hassan Ali Shahzad
fonte
Isso também é feito por padrão ... veja $this->_getClearSelect().
sv3n