Magento-Suche

Problemstellung: In der Magento-Suche finden sich bei der Suche nach "Ölen" Produkte aus Polen, bei der Suche nach "grün" jegliche Arten von Grundierungen und bei "Laser" alle Gläser des Shops.

Bei der Suche nach "Bio Honig" findet man auch "Bio Tofu" und bei "Haar Gel" Weißbier Gelee. Möchte man hier nicht auf die Volltextsuche umschalten, um die Fehleranfälligkeit gering zu halten, bietet sich eine Verfeinerung der Magento-Standard-Suchfunktion an:
Mit der Such-Einstellung "Combine (Like and Fulltext)" und der Erweiterung zweier Resource Models ist bereits eine grundlegende Verbesserung darstellbar:

Schritt 1: Modul erstellen, hier beispielhaft mit Namensraum "Econcess" und Modulnamen "EconSearch", Modul mit nur 3 Dateien (\app\code\local\Econcess\EconSearch\etc\config.xml, \app\code\local\Econcess\EconSearch\Model\Resource\Query.php und \app\code\local\Econcess\EconSearch\Model\Resource\Fulltext.php) und Magento mit \app\etc\modules\Econcess_EconSearch.xml bekannt geben.

Inhalt der \app\etc\modules\Econcess_EconSearch.xml:


<config>
<modules>
<Econcess_EconSearch>
<active>true</active>
<codePool>local</codePool>
</Econcess_EconSearch>
</modules>
</config>

Inhalt der \app\code\local\Econcess\EconSearch\etc\config.xml:

<?xml version="1.0"?>
<config>
<modules>
<Econcess_EconSearch>
<version>1.0.0</version>
</Econcess_EconSearch>
</modules>
<global>
<models>
<econsearch>
<class>Mage_CatalogSearch_Model</class>
</econsearch>
<catalogsearch_resource>
<class>Mage_CatalogSearch_Model_Resource</class>
<rewrite>
<fulltext>Econcess_EconSearch_Model_Resource_Fulltext</fulltext>
<query>Econcess_EconSearch_Model_Resource_Query</query>
</rewrite>
</catalogsearch_resource>
</models>
</global>
</config>

Hier werden somit nur 2 Resource Models überschrieben bzw. erweitert.

Schritt 2: Überschreiben der Funktion loadByQuery() in \app\code\local\Econcess\EconSearch\Model\Resource\Query.php

class Econcess_EconSearch_Model_Resource_Query extends Mage_CatalogSearch_Model_Resource_Query
{
public function loadByQuery(Mage_Core_Model_Abstract $object, $value)
{
$select = $this->_getReadAdapter()->select()
->from($this->getMainTable())
->where('synonym_for=_utf8 ? COLLATE utf8_bin OR query_text=_utf8 ? COLLATE utf8_bin', $value)
->where('store_id=?', $object->getStoreId())
->order('synonym_for ASC')
->limit(1);
if ($data = $this->_getReadAdapter()->fetchRow($select)) {
$object->setData($data);
$this->_afterLoad($object);
}
return $this;
}
}

Schritt 3: Überschreiben der Funktion prepareResult() in \app\code\local\Econcess\EconSearch\Model\Resource\Fulltext.php

class Econcess_EconSearch_Model_Resource_Fulltext extends Mage_CatalogSearch_Model_Resource_Fulltext
{
public function prepareResult($object, $queryText, $query)
{
$adapter = $this->_getWriteAdapter();
if (!$query->getIsProcessed()) {
$searchType = $object->getSearchType($query->getStoreId());
$preparedTerms = Mage::getResourceHelper('catalogsearch')
->prepareTerms($queryText, $query->getMaxQueryWords());
$bind = array();
$like = array();
$likeCond = '';
if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE
|| $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE
) {
$helper = Mage::getResourceHelper('core');
$words = Mage::helper('core/string')->splitWords($queryText, true, $query->getMaxQueryWords());
foreach ($words as $word) {
$like[] = $helper->getCILike('s.data_index', $word, array('position' => 'any'));
}
if ($like) {
$likeCond = '(' . join(' AND ', $like) . ' COLLATE utf8_bin)';
$likeCond = str_replace('LIKE', 'LIKE _utf8', $likeCond);
}
}
$mainTableAlias = 's';
$fields = array(
'query_id' => new Zend_Db_Expr($query->getId()),
'product_id',
);
$select = $adapter->select()
->from(array($mainTableAlias => $this->getMainTable()), $fields)
->joinInner(array('e' => $this->getTable('catalog/product')),
'e.entity_id = s.product_id',
array())
->where($mainTableAlias.'.store_id = ?', (int)$query->getStoreId());
if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_FULLTEXT
|| $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) {
$bind[':query'] = implode(' ', $preparedTerms[0]);
$where = Mage::getResourceHelper('catalogsearch')
->chooseFulltext($this->getMainTable(), $mainTableAlias, $select);
}
if ($likeCond != '' && $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) {
$where .= ($where ? ' OR ' : '') . $likeCond;
}
if ($likeCond != '' && $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE) {
$select->columns(array('relevance' => new Zend_Db_Expr(0)));
$where = $likeCond;
}
if ($where != '') {
$select->where($where);
}
$sql = $adapter->insertFromSelect($select,
$this->getTable('catalogsearch/result'),
array(),
Varien_Db_Adapter_Interface::INSERT_ON_DUPLICATE);
$adapter->query($sql, $bind);
$query->setIsProcessed(1);
}
return $this;
}
}

Fertig!

... zurück zum Blog