/** * Retrieve array with products counts per attribute option * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter The current catalog filter * * @return array */ public function getCount($filter) { $catalogResource = Mage::getResourceModel("catalog/product"); $attribute = $filter->getAttributeModel(); /** * For legacy SQL based attributes, Magento based the query on "catalog/product_index_eav", let him do */ if (in_array($attribute->getAttributeCode(), $catalogResource->getSqlAttributesCodes())) { return parent::getCount($filter); } /** * Since we have MongoDB, nothing is stored on eav index table for other attributes * Let's build the query with an aggregation * * @see http://docs.mongodb.org/manual/reference/operator/aggregation/ */ $collection = clone $filter->getLayer()->getProductCollection(); /** @var Smile_MongoCore_Model_Resource_Connection_Adapter $adapter */ $adapter = Mage::getSingleton('mongocore/resource_connection_adapter'); $queryBuilder = $adapter->getQueryBuilder(); $collectionName = Mage::getResourceModel('catalog/product')->getEntityTable(); $docCollection = $adapter->getCollection($collectionName); /** Build a condition to have all products which have the specified attribute as "notnull" AND not an empty string */ $scopedAttributeName = 'attr_' . $filter->getStoreId() . '.' . $attribute->getAttributeCode(); $globalAttributeName = 'attr_' . Mage_Core_Model_App::ADMIN_STORE_ID . '.' . $attribute->getAttributeCode(); $filterCascade = array('$or' => array(array('$and' => array(array($scopedAttributeName => array('$exists' => 1)))), array('$and' => array(array($scopedAttributeName => array('$exists' => 0)), array($globalAttributeName => array('$exists' => 1)))))); $documentFilter = $filterCascade; $documentFilter['$or'][0]['$and'][] = array($scopedAttributeName => array('$' . "ne" => 'null')); $documentFilter['$or'][0]['$and'][] = array($scopedAttributeName => array('$' . "ne" => '')); $documentFilter['$or'][1]['$and'][] = array($globalAttributeName => array('$' . "ne" => 'null')); $documentFilter['$or'][1]['$and'][] = array($globalAttributeName => array('$' . "ne" => '')); /** First, the matching, current product ids, and our calculated document filter **/ $match = array('$and' => array($queryBuilder->getIdsFilter($collection->getAllIds()), $documentFilter)); /** And then, the grouping, by attribute values, and calculating a sum */ $group = array("_id" => array("{$scopedAttributeName}" => '$' . $scopedAttributeName, "{$globalAttributeName}" => '$' . $globalAttributeName), "total" => array('$sum' => 1)); /** Building aggregation pipeline based on match and group previously built */ $pipeline = array(array('$match' => $match), array('$group' => $group)); $aggregation = $docCollection->aggregate($pipeline); /** * Now parse the aggregation result * Goal is to obtain an array like this : * * <attribute option id> => <total number of occurences> */ $aggregationResult = array(); if ($aggregation['ok'] == 1 && isset($aggregation["result"])) { foreach ($aggregation["result"] as $aggregate) { if (isset($aggregate["_id"]) && isset($aggregate['total'])) { $option = null; foreach ($aggregate["_id"] as $value) { $option = $value; } if (!is_null($option)) { $aggregationResult[$option] = $aggregate['total']; } } } } return ksort($aggregationResult); }
public function getCount($filter) { if (!Mage::helper('sm_shopby')->isEnabled()) { return parent::getCount($filter); } $select = clone $filter->getLayer()->getProductCollection()->getSelect(); $select->reset(Zend_Db_Select::COLUMNS); $select->reset(Zend_Db_Select::ORDER); $select->reset(Zend_Db_Select::LIMIT_COUNT); $select->reset(Zend_Db_Select::LIMIT_OFFSET); $connection = $this->_getReadAdapter(); $attribute = $filter->getAttributeModel(); $tableAlias = sprintf('%s_idx', $attribute->getAttributeCode()); $conditions = array("{$tableAlias}.entity_id = e.entity_id", $connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()), $connection->quoteInto("{$tableAlias}.store_id = ?", $filter->getStoreId())); $parts = $select->getPart(Zend_Db_Select::FROM); $from = array(); foreach ($parts as $key => $part) { if (stripos($key, $tableAlias) === false) { $from[$key] = $part; } } $select->setPart(Zend_Db_Select::FROM, $from); $select->join(array($tableAlias => $this->getMainTable()), join(' AND ', $conditions), array('value', 'count' => new Zend_Db_Expr("COUNT({$tableAlias}.entity_id)")))->group("{$tableAlias}.value"); return $connection->fetchPairs($select); }
/** * Retrieve array with products counts per attribute option * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @return array */ public function getCount($filter) { if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) { return parent::getCount($filter); } $collection = $filter->getLayer()->getProductCollection(); if (!method_exists($collection, 'checkSearchaniseResult') || !$collection->checkSearchaniseResult()) { return parent::getCount($filter); } return $collection->getSearchaniseRequest()->getCountAttribute($filter); }