Magento Search: Getting Better Results In Product Searches

Magento is a whopping big platform – even the community edition is something of a beast. That gives it a nasty learning curve, and while, in most cases, it simply works, there are some places where it tries to be clever, with mixed results.

The product search is a case in point. A friend was recently trying to get it to cooperate, but the way the results were being returned made it quite unusable. By default, the search uses an OR comparison to find what you’re after, so if you look for “web development books”, it will give you any product whose description contains “web”, “development”, or “books”. Since the order or relation of the words is not considered, you might end up with Twilight as a top result, which I’m sure you’ll agree, is not conductive to your users not gutting you with a rusty fork.

The easiest way I found to fix this, is to change the search query, defined by the fulltext.php file (/app/code/core/Mage/CatalogSearch/Model/Mysql4/fulltext.php). Since this is a core file, I would not recommend modifying it directly; make a copy in /app/code/local/Mage/CatalogSearch/Model/Mysql4. This is Magento’s natural mechanism to allow you to override its files; if you make changes directly in core, then they will be overwritten every time you update. So, don’t.

In fulltext.php, find the following code in the prepareResult method, and modify it as follows:

$words = $stringHelper->splitWords($queryText, true, $query->getMaxQueryWords());
$likeI = 0;

foreach ($words as $word) {
    $like[] = '`s`.`data_index` LIKE :likew' . $likeI;
    $bind[':likew' . $likeI] = '%' . $word . '%';
    $likeI ++;
}

to:

$like[] = '`s`.`data_index` LIKE :likew';
$bind[':likew'] = '%' . $queryText . '%';

In the administration site, change the search settings to use “Like” search mode. This dumbs down the search a little, making it look only for entries where the description contains an exact match for the search phrase. In this case,  if we look for “web development books”, we’d only get books whose description says that. While some weirdly labelled products may slip this search net, the results have been more relevant, and it certainly saves us from sparkly vampires and other bad literature.

47 Replies to “Magento Search: Getting Better Results In Product Searches”

  1. Don’t understand, mine fulltext.php is empty:

    <?php
    /**
    * Magento
    *
    * NOTICE OF LICENSE
    *
    * This source file is subject to the Open Software License (OSL 3.0)
    * that is bundled with this package in the file LICENSE.txt.
    * It is also available through the world-wide-web at this URL:
    * http://opensource.org/licenses/osl-3.0.php
    * If you did not receive a copy of the license and are unable to
    * obtain it through the world-wide-web, please send an email
    * to license@magentocommerce.com so we can send you a copy immediately.
    *
    * DISCLAIMER
    *
    * Do not edit or add to this file if you wish to upgrade Magento to newer
    * versions in the future. If you wish to customize Magento for your
    * needs please refer to http://www.magentocommerce.com for more information.
    *
    * @category Mage
    * @package Mage_CatalogSearch
    * @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
    * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
    */

    /**
    * CatalogSearch Fulltext Index resource model
    *
    * @category Mage
    * @package Mage_CatalogSearch
    * @author Magento Core Team
    */
    class Mage_CatalogSearch_Model_Mysql4_Fulltext extends Mage_CatalogSearch_Model_Resource_Fulltext
    {
    }

  2. Hi Vincas! Thanks for pointing this out.

    I was working on an older version of Magento – 1.4.2, if I remember correctly. From your code, it appears that in the version you are using, the MySQL class is delegating all the work to the Mage_CatalogSearch_Model_Resource_Fulltext class, which lives in app\code\core\Mage\CatalogSearch\Model\Resource\FullText.php.

    Have just downloaded Magento Community Edition 1.6.2 and confirmed this – the prepareResult function we are talking about is there. In this case, you can still follow the instructions above, using this file path instead of the one in the post (i.e. the overridden file would go into /app/code/local/Mage/CatalogSearch/Model/Resource instead of …/Model/MySQL4)

  3. Ok, now bigger file 🙂

    But i can’t find these lines:
    $words = $stringHelper->splitWords($queryText, true, $query->getMaxQueryWords());
    $likeI = 0;

    foreach ($words as $word) {
    $like[] = ‘`s`.`data_index` LIKE :likew’ . $likeI;
    $bind[‘:likew’ . $likeI] = ‘%’ . $word . ‘%’;
    $likeI ++;
    }

    I just found similar:
    $like[] = $helper->getCILike(‘s.data_index’, $word, array(‘position’ => ‘any’));

    if I need to change this line?

  4. Hello again,

    Yes, that should be it. In the end, you want $like to be an array with 1 element, which would be your search term.

    You might want to call escapeLikeValue on the search term before you add it in though – that will escape any characters which may cause trouble in the query.

    Remember to switch the search mode to LIKE in the admin, otherwise this change will be bypassed 🙂

  5. Sorry, I’m a little bit newbie.

    So I don’t understand something:
    this line:

    $like[] = $helper->getCILike(‘s.data_index’, $word, array(‘position’ => ‘any’));

    need change to:

    $like[] = ‘`s`.`data_index` LIKE :likew’;
    $bind[‘:likew’] = ‘%’ . $queryText . ‘%’;

    ?

  6. Don’t worry. Replace the following block.

    $words = Mage::helper(‘core/string’)->splitWords($queryText, true, $query->getMaxQueryWords());
    foreach ($words as $word) {
    $like[] = $helper->getCILike(‘s.data_index’, $word, array(‘position’ => ‘any’));
    }

    The reasoning behind it is that we don’t want the words split up. The foreach ($words …) { .. } loop would create an array like

    0: LIKE ‘word1’
    1: LIKE ‘word2’

    Which would end up as “Where (data_index LIKE ‘word1’ OR data_index LIKE ‘word2’)” etc. By replacing that block, you keep the search terms together, and so only get one condition for the like block: (data_index LIKE ‘%word1 word2%’).

    Let me know how it goes!

  7. I added like this:

    $like[] = $helper->getCILike(data_index LIKE ‘%word1 word2%’);

    and now getting error:

    Parse error: syntax error, unexpected T_STRING in /home/aparatur/domains/aparaturine.lt/public_html/app/code/core/Mage/CatalogSearch/Model/Resource/Fulltext.php on line 356

  8. No, no 🙂 that was just an example 🙂 You need to add this. My bad, was not very clear there.

    $like[] = ‘`s`.`data_index` LIKE :likew’;
    $bind[‘:likew’] = ‘%’ . $queryText . ‘%’;

  9. Also, I notice you’re editing in the core folder structure. Don’t do that, as any time you update, it will wipe your changes. Instead, create a new folder here:

    /home/aparatur/domains/aparaturine.lt/public_html/app/code/local/Mage/CatalogSearch/Model/Resource/

    Copy Fulltext.php there and make changes in the new file, not the old one.

  10. Parse error: syntax error, unexpected ‘`’ in /home/aparatur/domains/aparaturine.lt/public_html/app/code/local/Mage/CatalogSearch/Model/Resource/Fulltext.php on line 353

    😀

  11. :/ Try removing the ` quotes around s.data_index, and make sure all the single quote characters are use this character: ‘

  12. Parse error: syntax error, unexpected T_STRING in /home/aparatur/domains/aparaturine.lt/public_html/app/code/local/Mage/CatalogSearch/Model/Resource/Fulltext.php on line 353

    Could you send me edited fulltext.php file how you imagine.

    My email [email removed].

  13. [Resolved over email]

    The fix was applied as above. There was some problem with character encoding, but the query worked fine after that was resolved.

  14. Hi,

    I’m using Enterprise version 1.11. Does it works for enterprise version as well? I want to keep fulltext search not keyword search.

    Your help appreciated in advance.

    Cheers.

  15. Hi Niraj! I have not had time to check enterprise 1.11, but the full text search code is probably the same. You might need to run a search for the exact position of the code – it was moved around between community 1.4 and community 1.6, so it might not be in the same exact file, but the code itself is the same, and the modification should work anyway.

  16. This worked better for me (Magento CE 1.7.0.2):

    Make a copy of

    app/code/core/Mage/CatalogSearch/Model/Resource/Fulltext.php
    to
    app/code/local/Mage/CatalogSearch/Model/Resource/Fulltext.php

    In the new file, change the line 331

    $likeCond = ‘(‘ . join(‘ OR ‘, $like) . ‘)’;
    to
    $likeCond = ‘(‘ . join(‘ AND ‘, $like) . ‘)’;

    I think (data_index LIKE ‘%word1%’ AND ‘%word2%’) is smarter than (data_index LIKE ‘%word1 word2%’)

    1. Thanks for your comment, Leandro! Your modification can be very useful in some cases. It depends on what you want your search results to return. LIKE %word1% AND %word2% will give you items which contain both words; LIKE %word1 word2% will give you items matching a phrase. So it’s a case of deciding which one would be more useful for your users.

  17. can you tell me how i need to modify it exactly?

    foreach ($words as $word) {
    $like[] = $helper->getCILike(‘s.data_index’, $word, array(‘position’ => ‘any’));
    }
    if ($like) {
    $likeCond = ‘(‘ . join(‘ OR ‘, $like) . ‘)’;
    }

    This is found in the file, but i realy don’t know how to change it.

    Thanks! (magento 1.7) (already made a copy in the local folder)

  18. Hi Richard. Just remove that block and put the following code instead:

    $like[] = ‘`s`.`data_index` LIKE :likew’;
    $bind[‘:likew’] = ‘%’ . $queryText . ‘%’;

  19. Hi karl,

    I am having a headache with the Magento search function. I have made changes to Fulltext.php as guided and currently it sites at:

    $helper = Mage::getResourceHelper(‘core’);
    $like[] = ‘`s`.`data_index` LIKE :likew’;
    $bind[‘:likew’] = ‘%’ . $queryText . ‘%’;
    }
    if ($like) {
    $likeCond = ‘(‘ . join(‘ OR ‘, $like) . ‘)’;

    No errors just no changes!
    I have changed OR to AND also but I can’t see any changes. Might try an extension out but thanks anyway 🙂

  20. Im having trouble following this too but the main problem it seem is that the character encoding on the apostrophe (‘) is being replaced with something else and breaking the code

  21. Hey Karl would it be possible for you to send me a copy of the Fulltext.php file as well? I’ve tried to get this work in every way possible but I keep getting errors.

  22. Hi Karl,

    I am running into the same situation as Steve pointed out before. I have performed the suggested changes (done in the local folder) but they do not affect in any way the search results. I am also working with Magento 1.7. Do you have some new insights on how to cope with the problem? Thanks!

  23. Hi Steve, Sylvia – did you switch the search mode to “Like” in the search options in the admin? If not, the search function will not hit this chunk of code. Other than that, no idea at the moment – haven’t looked into 1.7 yet.

    Nightcrwlr – what version of magento are you using? I don’t have access to the edited file any more, but if it’s just an encoding issue, you should be able to use any text editor to replace the apostrophes and save the file correctly.

  24. Hello,

    I did it on magento 1.4.1 and its working fine! Nice job!

    But i have a question, i’m try do to do it on magento 1.7 and don’t work!

    I read all reply here and the only solution you send to Vincas by email,

    Please, send me the file or tell me where i edit to do it work here.

    Thanks a lot.

    1. Hello Bruno, thanks for the comment!

      The fix sent by email was the same change described in this post, saved in utf-8 encoding if I recall correctly; the problem was caused by copying and pasting from this page, which messed up the single quotes. I haven’t tried it on 1.7 so I’m not sure if there are any changes in Magento, but if you have any error messages, let me know, might be able to help.

  25. Hi Karl,

    My magento site is not returning expected results. Suppose, If I simply copy the product name and put it into the search bar. It returns just the random results. Any help would be really appreciated.

    Thanks

  26. Hello,

    I’m using magento 1.7 and I tried all the things described above but it is not improving my search results. what else can I do to improve my results.

    Thanks

  27. Hi Jatin. The problem you mention is pretty much what we were seeing before the changes in this post – the results are not really random, but Magento seems to consider only the description when returning search results, rather than the name of the product.

    I haven’t been following this up since I don’t use Magento personally, but you might want to check up with Vincas (see comments, above) or Bruno – some functions have moved around between versions.

    The part where it says [Resolved over email] just means that the changes were applied as discussed in the previous comments – there was an issue regarding text encoding, so make sure you save your files as UTF-8. Hope that helps!

  28. Hello,

    I have a problem with my magento site, no matter the one I choose (Like, Fulltext or Combine) the result search for “sony xperia u” doen’t show directly this product. I try every fix on the net. Can’t get it working. I’m using magento 1.7. Can anyone help me ?

    I’ve noticed this in the address bar

    /catalogsearch/result/?q=sony+xperia+t

    But I need it to be /catalogsearch/result/?q=’sony xperia t’
    my site name is houssehouse.com (Please check and remove the domain name from here once you’re done or you can leave it it will be a page rank.

    PS : I’m french guy so sorry for mistakes you might read.

    Thanks

    1. Hi momlic! The query in the address bar looks ok, seems to be url encoded correctly. The server should clean it up on its own. If you need the quotes, you can add them in the search submit form, but it would be better to use the normal system unless you have specific requirements.

  29. Thank Karl for sharing it. It is very good. I applied it to my client site and it helped improve search result. I also notice that I have to Re-index to get the change to work.

  30. When I move the Fulltext.php from core folder to local folder, After changing the class name also, it is not working. It is wokring when I make class name with “Mage” and the same name with folders then it works fine. But when I make another name instead of “Mage” then it is not working. So what is the issue for my code?

    1. Hi Johngrews, thank you for your message! What version are you using? Sounds like it depends on the class naming.

  31. Karl,
    I am using Magento ver. 1.7.0.2.I have updated the code as you have told.but getting this error.
    Parse error: syntax error, unexpected T_STRING in /home/sandlot/public_html/app/code/local/Mage/CatalogSearch/Model/Resource/Fulltext.php on line 327.
    Can you please email me Fulltext.php with update code ?

    Thanks

  32. AM running magento 1.7.0.2 too. Been trying out the suggestions by changing the “OR” to “LIKE”, but my results has not changed. Magento still uses the “OR” algorithm and not giving my site accurate search results.

    Anyone have anymore solutions that i can try? 🙁

  33. For everyone having issues with this, my code looks like this and works well…

    $helper = Mage::getResourceHelper(‘core’);
    $like[] = $like[] = $helper->getCILike(‘s.data_index’, $queryText, array(‘position’ => ‘any’));
    if ($like) {
    $likeCond = ‘(‘ . join(‘ AND ‘, $like) . ‘)’;
    }

    This is for all of the people on here having troubles with later versions of Magento. To me it seems as though Magento is no longer using $bind for like. The getCILike I believe has replaced this. I could be wrong, but try it out. It seems to be working well for me.

  34. I am seeking the same results on Magento CE 1.9.x
    The file to be edited is very short, I have search some of the other areas where this same file name exists, but have been unable to find the lines indicated. I assume the coding has changed some since this original posting as well as the comments. Can anyone shed some light on what needs to be edited in the current version of CE to have the same effect?

    My fulltext.php located in the directory tree contains:

    <?php
    /**
    * Magento
    *
    * NOTICE OF LICENSE
    *
    * This source file is subject to the Open Software License (OSL 3.0)
    * that is bundled with this package in the file LICENSE.txt.
    * It is also available through the world-wide-web at this URL:
    * http://opensource.org/licenses/osl-3.0.php
    * If you did not receive a copy of the license and are unable to
    * obtain it through the world-wide-web, please send an email
    * to license@magentocommerce.com so we can send you a copy immediately.
    *
    * DISCLAIMER
    *
    * Do not edit or add to this file if you wish to upgrade Magento to newer
    * versions in the future. If you wish to customize Magento for your
    * needs please refer to http://www.magentocommerce.com for more information.
    *
    * @category Mage
    * @package Mage_CatalogSearch
    * @copyright Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
    * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
    */

    /**
    * CatalogSearch Fulltext Index resource model
    *
    * @category Mage
    * @package Mage_CatalogSearch
    * @author Magento Core Team
    */
    class Mage_CatalogSearch_Model_Mysql4_Fulltext extends Mage_CatalogSearch_Model_Resource_Fulltext
    {
    }

    Thanks,
    – Dennis

    1. Hi Dennis!

      The file you posted is actually an overriding class which provides extension points for Mage_CatalogSearch_Model_Resource_Fulltext
      That is probably the file you should be looking at. I haven’t been keeping up with Magento, so I have no idea where that would be in the more recent versions.

  35. This is to confirm the above solution posted by Adam on May 20, 2014 works perfectly on Magento 1.9.1.0.

  36. I was looking for something like this. Thanks!
    But I installed the extension to solve the problem of irrelevant Magento search, it helps choose search type as like, fulltext or combined. I like the last option most but I’m still testing.
    Here is the extension I’m talking about https://amasty.com/search-pro.html

Comments are closed.