Search Type: Like, Full Text or Combined?

Everyone always complains about Magento search but I believe it can work really well if you spend time planning and configuring it properly.


Like

Keyword based search method, breaking your query into individual words. See the following from line 326 in class Mage_CatalogSearch_Model_Resource_Fulltext::prepareResult()

            $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(' OR ', $like) . ')';
            }

You can see it splits each word in your search query and joins them together in LIKE statements - you end up with something like this:

WHERE `attribute` LIKE 'my' OR `attribute` LIKE 'search' OR `attribute` LIKE 'query'

This method might work for certain store setups where product names are simple and customers search for very specific items, but in my experience it is not a good choice.


Fulltext

Relevance based search - every search query is graded accoring to a score assigned based on MySQL's MATCH ... AGAINST query. You can see this in action in Mage_CatalogSearch_Model_Resource_Helper_Mysql4 line 44:

public function chooseFulltext($table, $alias, $select)
{
    $field = new Zend_Db_Expr('MATCH ('.$alias.'.data_index) AGAINST (:query IN BOOLEAN MODE)');
    $select->columns(array('relevance' => $field));
    return $field;
}

The database table Magento uses when performing fulltext searches is catalogsearch_fulltext. An example value:

EmCO0014e|Emma Certified|Emma Certified Organic Herbal Tonic Mist TRIAL/TRAVEL|Australian|Certified Organic|Palm Oil Free|Nut Free|Vegan Suitable|

These values are directly linked to the attributes you specify as 'Use in Quick Search' under Catalog > Attributes > Manage Attributes


Combine

Pretty self explanatory. Take a look at line 354 of Mage_CatalogSearch_Model_Resource_Fulltext:

        if ($likeCond != '' && $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) {
                $where .= ($where ? ' OR ' : '') . $likeCond;
        } elseif ($likeCond != '' && $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE) {
            $select->columns(array('relevance'  => new Zend_Db_Expr(0)));
            $where = $likeCond;
        }

You can see it just adds the LIKE results after FULLTEXT results have come back.


Things to note

  1. I strongly recommend using FULLTEXT for better performance and relevant results
  2. Go through each attribute and consider whether or not it is necessary to add it to the fulltext index ('Use in quick search')
  3. By default the product descriptions are included in the FULLTEXT indexing. I almost always remove the descriptions as they pollute the relevance scores with words used in irrelevant contexts.
  4. Make sure your meta attributes are used in the fulltext index. Populate them with meaningful content.
  5. MySQL FULLTEXT has some quirks - it has a list of ignored words which can be problematic if your product names are made up of these words!
  6. MySQL by default ignores FULLTEXT queries under 4 characters. Attributes with short values will be ignored unless you change this value.

You can work around points 5 & 6 by using the Combine method - the LIKE results should compensate for any words FULLTEXT ignored.


The "like" search will do the usual like match, using a like '%keyword%' query. One advantage of this type of search is that it will match partial words. It has serious drawbacks though:

  • will quickly become a performance issue
  • relevance is bad. There is actually no concept of "relevance" in like queries

Fulltext search will work using the MyISAM fulltext search (http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html). You should read about it, but in a nutshell:

  • performance is better
  • it will exclude stopwords (like "and", "with" etc)
  • It will assign a score by default to each result based on relevance

The drawback of fulltext is that it cannot do partial matches, i.e. a search for "pho" will not find "phone"

The "combined" search will use a "like" condition to match the results but will also take into consideration the fulltext search score for sorting them. This means that you will get more results (as like search will do partial matches too) and they will also be ordered better because of the fulltext score.

As other people said, if you are serious about search you should be using Solr. It is way faster and a lot more relevant. You would have to own Magento EE and install Solr yourself though.


They're direct references to the type of query Magento will use. Personally I think Full Text search is more powerfull and performance is better, especially if LIKE is used with wildcards (%). A combination of both will probably be most accurate but might be overkill. I'd stick with the Full text.

But if you're looking for a powerfull search solution check out this project: https://code.google.com/p/magento-solr/. SOLR was build for searching large collections and while it might take some time to implement it should be worth it. Personally I've never used it in Magento before but in on other PHP projects it performed very well.

Full text documentation can be found here: http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html LIKE documentation here: http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html