Sometimes a search engine might stop working. There are various reasons: it may be caused by migrating the store to a different server, updating Magento to a more recent version, or by other changes which were not supposed to affect the search module.
Where should we start debugging the search engine problems? It’s best to begin with a standard procedure followed when a functionality breaks: first, go to System -> Index Management and perform re-indexing (preferably all data). Then, clear the cache (System -> Cache Management).
What is Index Management responsible for?
As you know, product and category attributes in Magento are based on EAV entities. This is very flexible, but also difficult in terms of optimization. Indexes transform the EAV structure into one flat table for each store view and, as a result, every operation is performed via an optimized database query.
The Catalog Search Index, that is of interest to us in this case, generates such entry with many attributes, on the basis of which we can search products.
Secondly, you need to verify whether the products are visible in the search engine. You can check it in Catalog -> Manage Products. The option Visibility should include Search.
You should also check the attributes that you’re using to search products. To do so, go to Catalog -> Manage Attributes and confirm that the option Searchable is set to “Yes” for the attribute in question (e.g. Name).
If all the above methods fail and the search engine still doesn’t work, you can implement the fix presented below. As we know from experience, it helps when the search engine stops working after an update to a newer version. However, recently it has also helped us when the search engine wasn’t working even though there hasn’t been any update.
How does the fix work?
In short, it consists in overwriting two methods from the Magento search result block (app/code/core/Mage/CatalogSearch/Block/Result.php).
In line with the good practice, we won’t edit Magento core files. We’ll simply create a separate module that will be responsible for displaying the search results. You can disable it in the backend any time.
So let’s create our SearchFix!
//app/etc/modules/Magently_SearchFix.xml
<?xml version="1.0"?>
<config>
<modules>
<Magently_SearchFix>
<active>true</active>
<codePool>local</codePool>
</Magently_SearchFix>
</modules>
<global>
<blocks>
<catalogsearch>
<rewrite>
<result>Magently_SearchFix_Block_Result</result>
</rewrite>
</catalogsearch>
</blocks>
</global>
</config>
In the blocks, we refer to the Magento CatalogSearch module and we overwrite the result block with our fix.
Now, let’s create our module’s config where we’ll declare our block’s class.
//app/code/local/Magently/SearchFix/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Magently_SearchFix>
<version>1.0.0</version>
</Magently_SearchFix>
</modules>
<global>
<blocks>
<magently_searchfix>
<class>Magently_SearchFix_Block</class>
</magently_searchfix>
</blocks>
</global>
</config>
Then we create a class that extends the Mage_CatalogSearch_Block_Result class.
//app/code/local/Magently/SearchFix/Block/Result.php
<?php
class Magently_SearchFix_Block_Result extends Mage_CatalogSearch_Block_Result {
public function setListCollection()
{
$this->getListBlock()
->setCollection($this->_getProductCollection());
return $this;
}
protected function _getProductCollection()
{
if (is_null($this->_productCollection)) {
$this->_productCollection = Mage::getSingleton('catalogsearch/layer')->getProductCollection();
}
return $this->_productCollection;
}
}
If we look at the core files (app/code/core/Mage/CatalogSearch/Block/Result.php), we’ll notice that the setListCollection() method is commented out and returns only $this. The _getProductCollection() method, however, now returns singleton, that is a single instance with a collection of products.
Below you can review the differences between the methods.
1. Originally:
//app/code/core/Mage/CatalogSearch/Block/Result.php
public function setListCollection()
{
// $this->getListBlock()
// ->setCollection($this->_getProductCollection());
return $this;
}
Overwritten by:
//app/code/local/Magently/SearchFix/Block/Result.php
public function setListCollection()
{
$this->getListBlock()
->setCollection($this->_getProductCollection());
return $this;
}
2. Originally:
//app/code/core/Mage/CatalogSearch/Block/Result.php
protected function _getProductCollection()
{
if (is_null($this->_productCollection)) {
$this->_productCollection = $this->getListBlock()->getLoadedProductCollection();
}
return $this->_productCollection;
}
Overwritten by:
//app/code/local/Magently/SearchFix/Block/Result.php
protected function _getProductCollection()
{
if (is_null($this->_productCollection)) {
$this->_productCollection = Mage::getSingleton('catalogsearch/layer')->getProductCollection();
}
return $this->_productCollection;
}
Once you’ve overwritten the methods as described above, repeat the steps mentioned at the beginning (re-index data and clear the cache). Then check again – your search engine should be working again!