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.
No related posts.
Good find dude
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
{
}
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)
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?
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
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 . ‘%’;
?
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!
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
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 . ‘%’;
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.
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
:/ Try removing the ` quotes around s.data_index, and make sure all the single quote characters are use this character: ‘
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].
[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.