Magento – Volltextsuche optimieren

In Magento gibt es einen ziemlich fiesen Bug bei der Volltextsuche.
Das Problem ist, dass die Ergebnisse bei der Volltextsuche zwar nach der Relevanz der einzelnen Suchergebnisse sortiert wird, allerdings ist die Relevanz der Ergebnisse immer ‚1‘ und somit die Sortierung ziemlich unnütz. Das führt dazu, das häufig Produkte am Anfang der Suchergebnisseite stehen, nach denen der User gar nicht direkt gesucht hat.
Die Ursache für das Problem liegt in der SQL-Abfrage, mit der in Magento der Volltextindex abgefragt wird.
Die SQL Abfrage, die Magento bei der Volltextsuche ausführt, sieht wie folgt aus (wobei der relevante Teil das Select Statement ist):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
INSERT INTO `catalogsearch_result` 
 SELECT 
 12345 AS `query_id`, 
 `s`.`product_id`, 
 MATCH (s.data_index)
 AGAINST ("suchbegriff1 suchbegriff2" IN BOOLEAN MODE) AS `relevance` 
 FROM `catalogsearch_fulltext` AS `s`
 INNER JOIN `catalog_product_entity` AS `e` 
 ON e.entity_id = s.product_id 
 WHERE (s.store_id = 1) 
 AND 
 (MATCH (s.data_index) 
 AGAINST ("suchbegriff1 suchbegriff2" IN BOOLEAN MODE)) 
 ON DUPLICATE KEY UPDATE `relevance` = VALUES(`relevance`)

Wenn man diese Abfrage mal direkt in der Magento Datenbank ausführt sieht man, dass der Wert „relevance“ für jede Ergebniszeile „1“ ist.
Das liegt daran, dass der Wert „relevance“ wie folgt ermittelt wird:

1
2
3
4
...
MATCH (s.data_index)
 AGAINST ("suchbegriff1 suchbegriff2" IN BOOLEAN MODE) AS `relevance` 
...

Das Problem hierbei ist der Zusatz „IN BOOLEAN MODE“. Wenn man diesen Zusatz in der Spaltendefinition der Datenbankabfrage weglässt, so wird die Relevanz richtig ermittelt.
Also muss man die Abfrage wie folgt ändern:

1
2
3
4
...
MATCH (s.data_index)
 AGAINST ("suchbegriff1 suchbegriff2") AS `relevance` 
...

Weitere Infos dazu findet man in der offiziellen Mysql Doku.
Leider befindet sich der entscheidende Hinweise zu obigem „Phänomen“ nur in dem Kommtentar von Patrick O’Lone.

Die Ursachen für das Problem liegt an folgender Stellen im Magento Core:
Datei: Mage_CatalogSearch_Model_Resource_Helper_Mysql4

1
2
3
4
5
6
    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;
    }

Hier wird in der Variable $field der "Match Against" Ausdruck für die Volltextsuche definiert und sowohl in der „Column“-Definition als auch in der „Where“-Bedingung genutzt.
Um das Problem zu lösen, muss man den Code nur wie folgt ändern, so dass in der „Column“-Definition der Abfrage der Relevance ohne Boolen Mode berechnet wird:

1
2
3
4
5
6
// Use 'column' part without boolean mode
$field = new Zend_Db_Expr('MATCH ('.$alias.'.data_index) AGAINST (:query)');
$select->columns(array('relevance' => $field));
// Use 'where' part with boolean mode
$field = new Zend_Db_Expr('MATCH ('.$alias.'.data_index) AGAINST (:query IN BOOLEAN MODE)');
return $field;

Nun wird die Relevanz der einzelnen Suchergebnisse richtig berechnet.

Achtung: Die Änderungen sollten natürlich wie immer nicht direkt im Magento Core, sondern in einem eigenen Modul gemacht werden, dass das CatalogSearch Modul erweitert.

Es kann sein, dass das bei aktuellen Mysql Versionen nicht mehr auftritt, feststellen konnte ich den Bug bei folgendem Setup:

  • Magento Community Version: 1.7.0.2
  • Magento Enterprise Version: 1.12.0.2
  • Mysql Version: 5.5.25
Dieser Beitrag wurde unter Magento abgelegt und mit , , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Die Kommentarfunktion ist geschlossen.