First of all, I found similar questions in SO but there is not any answer for them. So, the first part of the question is a little bit duplicated. I want to improve search results in Magento. Here is what I've done already:
1. Search with AND
instead of OR
when there are multiple words.
2. Ajax search starts searching from anywhere and not only from the beginning of the fields.
3. Trim the last s
from the words to prevent empty results when searching with plurals.
4. I changed the search type from Like
to Fulltext
or Combine
but the results were not better and even were worst, so I leave it as is. It's Like
now, so there is no relevance
ordering.
The last thing which I want to try is adding this to the search query:
SELECT ... other non-full-text-cols
MATCH (product_title) AGAINST ('lean body for her') AS rel1,
MATCH (content) AGAINST ('lean body for her') AS rel2
FROM table
WHERE MATCH (product_title,content) AGAINST ('lean body for her')
ORDER BY (rel1*1.5)+(rel2)
Here is my query but I'm not sure if it would work because I can't test it:
$this->_productCollection->addAttributeToSelect(
array(
'rel1' => new Zend_Db_Expr('MATCH (name) AGAINST ("'.$queryText.'")'),
'rel2' => new Zend_Db_Expr('MATCH (short_description) AGAINST ("'.$queryText.'")')
)
);
$this->_productCollection->getSelect()
->where('MATCH (name,short_description) AGAINST ("'.$queryText.'")')
->order('(rel1*1.5)+(rel2)');
The main idea is to add bonus weight to a result if the search query is found in the title of the product. The problem is that I don't know where to modify the query. I can't find where it is at all. $this->_productCollection
is not the right object, I know it. I looked at all the Collection.php
files, resource models, models and even the query log but no luck. There are just little 1 or 2 row parts in some files but not a full query. I'm new to Magento and still have problems with finding this type of stuff. So, where I have to place my additional stuff when I have to extend a query?
Community Edition Magento, version 1.6.1.0.
Note: I know that some extension for improving search results will work much better than my solutions but for now I have to do it in that way. It would be a good experience for me, too.
Edit:
So, I figured out how to add my custom fields for the ordering but it's
untruly I think. In class Mage_CatalogSearch_Model_Layer extends Mage_Catalog_Model_Layer
's prepareProductCollection
method I added two joins to the query and get the fields rel1
and rel2
:
$collection->getSelect()->joinLeft(
array('cpev' => 'catalog_product_entity_varchar'),
'cpev.entity_id = e.entity_id AND cpev.attribute_id = 96',
array('rel1' => new Zend_Db_Expr('2.01*(LENGTH(cpev.value) - LENGTH(REPLACE(LCASE(cpev.value), LCASE("'.$queryText.'"), ""))) / LENGTH("'.$queryText.'")'))
);
$collection->getSelect()->joinLeft(
array('cpet' => 'catalog_product_entity_text'),
'cpet.entity_id = e.entity_id AND cpet.attribute_id = 506',
array('rel2' => new Zend_Db_Expr('(LENGTH(cpet.value) - LENGTH(REPLACE(LCASE(cpet.value), LCASE("'.$queryText.'"), ""))) / LENGTH("'.$queryText.'")'))
);
I have these fields now but as you can see I have hard coded stuff like attribute_id = 96
etc. which is not good at all and it will not work everytime - I checked these ids directly from the database tables. I wrote it like this because I haven't access to name
and short_description
fields but they are in the result. Don't know why. So, cpev.value
is name
field and cpet.value
is the short_description
field. Moreover I can't order the results by these fields. I tried $collection->addOrder('SUM(rel1+rel2)');
, $collection->getSelect()->order(new Zend_Db_Expr('SUM(rel1+rel2)').' DESC');
, some addAttributeToFilter
stuff etc. but it's not working.
Edit 2: I accepted @james' answer but finally we bought an extension for improving the search results.
In Mage_CatalogSearch_Model_Resource_Fulltext
check out prepareResult
(line 310 in 1.7 CE) and look for the following:
$select->columns(array('relevance' => new Zend_Db_Expr(0)));
Magento sets all search result relevances as 0 (!); add the relevances you want (higher is better) here. You can create a custom query in Zend_Db_Expr()
to generate higher relevances on attribute matches.
The answer to your first question (1): To make an AND search instead of OR, you will need to rewrite the class
Mage_CatalogSearch_Model_Resource_Fulltext
In the method
public function prepareResult($object, $queryText, $query)
you want to switch the part
$likeCond = '(' . join(' OR ', $like) . ')';
to
$likeCond = '(' . join(' AND ', $like) . ')';
Be sure to reindex the search index afterwards to have an effect.
来源:https://stackoverflow.com/questions/13947976/how-and-where-to-modify-magento-search-query