Index: branches/5.1.x/core/units/categories/categories_event_handler.php =================================================================== diff -u -N -r14371 -r14508 --- branches/5.1.x/core/units/categories/categories_event_handler.php (.../categories_event_handler.php) (revision 14371) +++ branches/5.1.x/core/units/categories/categories_event_handler.php (.../categories_event_handler.php) (revision 14508) @@ -1,6 +1,6 @@ $search_event($event); - $search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search'; - $sql = 'SHOW TABLES LIKE "'.$search_table.'"'; + $object =& $event->getObject(); + /* @var $object kDBList */ - if ($this->Conn->Query($sql)) { - $search_res_ids = $this->Conn->GetCol('SELECT ResourceId FROM '.$search_table); - } + $search_sql = ' FROM ' . TABLE_PREFIX . 'ses_' . $this->Application->GetSID() . '_' . TABLE_PREFIX . 'Search + search_result LEFT JOIN %1$s ON %1$s.ResourceId = search_result.ResourceId'; + $sql = str_replace('FROM %1$s', $search_sql, $object->SelectClause); - if (isset($search_res_ids) && $search_res_ids) { - $type_clauses['search']['include'] = '%1$s.ResourceId IN ('.implode(',', $search_res_ids).')'; - $type_clauses['search']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $search_res_ids).')'; - } - else { - $type_clauses['search']['include'] = '0'; - $type_clauses['search']['except'] = '1'; - } + $object->SetSelectSQL($sql); + $object->addCalculatedField('Relevance', 'search_result.Relevance'); + $object->AddOrderField('search_result.Relevance', 'desc', true); + + $type_clauses['search']['include'] = '1'; + $type_clauses['search']['except'] = '0'; $type_clauses['search']['having_filter'] = false; } @@ -2311,9 +2309,9 @@ } } - $where_clause = '(' . implode(') OR (', $where_clause) . ')'; + $where_clause = '((' . implode(') OR (', $where_clause) . '))'; // 2 braces for next clauses, see below! - $where_clause = $where_clause.' AND '.$items_table.'.Status=1'; + $where_clause = $where_clause . ' AND (' . $items_table . '.Status = ' . STATUS_ACTIVE . ')'; if ($event->MasterEvent && $event->MasterEvent->Name == 'OnListBuild') { if ($event->MasterEvent->getEventParam('ResultIds')) { @@ -2343,6 +2341,14 @@ $config_elem = $search_config[ $map_key ]; $weight = $config_elem['Priority']; + + // search by whole words only ([[:<:]] - word boundary) + /*$revelance_parts[] = 'IF('.$field.' REGEXP "[[:<:]]('.implode(' ', $positive_words).')[[:>:]]", '.$weight.', 0)'; + foreach ($positive_words as $keyword) { + $revelance_parts[] = 'IF('.$field.' REGEXP "[[:<:]]('.$keyword.')[[:>:]]", '.$weight.', 0)'; + }*/ + + // search by partial word matches too $revelance_parts[] = 'IF('.$field.' LIKE "%'.implode(' ', $positive_words).'%", '.$weight_sum.', 0)'; foreach ($positive_words as $keyword) { $revelance_parts[] = 'IF('.$field.' LIKE "%'.$keyword.'%", '.$weight.', 0)'; @@ -2389,9 +2395,16 @@ FROM '.$object->TableName.' '.implode(' ', $join_clauses).' WHERE '.$where_clause.' - GROUP BY '.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField'); + GROUP BY '.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField').' ORDER BY Relevance DESC'; $res = $this->Conn->Query($sql); + + if ( !$search_table_exists ) { + $sql = 'ALTER TABLE ' . $search_table . ' + ADD INDEX (ResourceId), + ADD INDEX (Relevance)'; + $this->Conn->Query($sql); + } } /** Index: branches/5.1.x/core/kernel/db/cat_event_handler.php =================================================================== diff -u -N -r14443 -r14508 --- branches/5.1.x/core/kernel/db/cat_event_handler.php (.../cat_event_handler.php) (revision 14443) +++ branches/5.1.x/core/kernel/db/cat_event_handler.php (.../cat_event_handler.php) (revision 14508) @@ -1,6 +1,6 @@ $search_event($event); - $search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search'; - $sql = 'SHOW TABLES LIKE "'.$search_table.'"'; + $object =& $event->getObject(); + /* @var $object kDBList */ - if ($this->Conn->Query($sql)) { - $search_res_ids = $this->Conn->GetCol('SELECT ResourceId FROM '.$search_table); - } + $search_sql = ' FROM ' . TABLE_PREFIX . 'ses_' . $this->Application->GetSID() . '_' . TABLE_PREFIX . 'Search + search_result LEFT JOIN %1$s ON %1$s.ResourceId = search_result.ResourceId'; + $sql = str_replace('FROM %1$s', $search_sql, $object->SelectClause); - if (isset($search_res_ids) && $search_res_ids) { - $type_clauses['search']['include'] = '%1$s.ResourceId IN ('.implode(',', $search_res_ids).') AND PrimaryCat = 1 AND ('.TABLE_PREFIX.'Category.Status = '.STATUS_ACTIVE.')'; - $type_clauses['search']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $search_res_ids).') AND PrimaryCat = 1 AND ('.TABLE_PREFIX.'Category.Status = '.STATUS_ACTIVE.')'; - } - else { - $type_clauses['search']['include'] = '0'; - $type_clauses['search']['except'] = '1'; - } + $object->SetSelectSQL($sql); + $object->addCalculatedField('Relevance', 'search_result.Relevance'); + $object->AddOrderField('search_result.Relevance', 'desc', true); + + $type_clauses['search']['include'] = 'PrimaryCat = 1 AND ('.TABLE_PREFIX.'Category.Status = '.STATUS_ACTIVE.')'; + $type_clauses['search']['except'] = 'PrimaryCat = 1 AND ('.TABLE_PREFIX.'Category.Status = '.STATUS_ACTIVE.')'; $type_clauses['search']['having_filter'] = false; } @@ -947,13 +945,13 @@ // linking existing images for item with virtual fields $image_helper =& $this->Application->recallObject('ImageHelper'); /* @var $image_helper ImageHelper */ - + $image_helper->LoadItemImages($object); - + // linking existing files for item with virtual fields $file_helper =& $this->Application->recallObject('FileHelper'); /* @var $file_helper FileHelper */ - + $file_helper->LoadItemFiles($object); } @@ -1231,7 +1229,7 @@ } } - $where_clause = '(' . implode(') OR (', $where_clause) . ')'; + $where_clause = '((' . implode(') OR (', $where_clause) . '))'; // 2 braces for next clauses, see below! $search_scope = $this->Application->GetVar('search_scope'); if ($search_scope == 'category') { @@ -1245,7 +1243,7 @@ } } - $where_clause = $where_clause.' AND '.$items_table.'.Status=1'; + $where_clause = $where_clause . ' AND (' . $items_table . '.Status = ' . STATUS_ACTIVE . ')'; if ($event->MasterEvent && $event->MasterEvent->Name == 'OnListBuild') { if ($event->MasterEvent->getEventParam('ResultIds')) { @@ -1275,6 +1273,14 @@ $config_elem = $search_config[ $map_key ]; $weight = $config_elem['Priority']; + + // search by whole words only ([[:<:]] - word boundary) + /*$revelance_parts[] = 'IF('.$field.' REGEXP "[[:<:]]('.implode(' ', $positive_words).')[[:>:]]", '.$weight.', 0)'; + foreach ($positive_words as $keyword) { + $revelance_parts[] = 'IF('.$field.' REGEXP "[[:<:]]('.$keyword.')[[:>:]]", '.$weight.', 0)'; + }*/ + + // search by partial word matches too $revelance_parts[] = 'IF('.$field.' LIKE "%'.implode(' ', $positive_words).'%", '.$weight_sum.', 0)'; foreach ($positive_words as $keyword) { $revelance_parts[] = 'IF('.$field.' LIKE "%'.$keyword.'%", '.$weight.', 0)'; @@ -1321,9 +1327,16 @@ FROM '.$object->TableName.' '.implode(' ', $join_clauses).' WHERE '.$where_clause.' - GROUP BY '.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField'); + GROUP BY '.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField').' ORDER BY Relevance DESC'; $res = $this->Conn->Query($sql); + + if ( !$search_table_exists ) { + $sql = 'ALTER TABLE ' . $search_table . ' + ADD INDEX (ResourceId), + ADD INDEX (Relevance)'; + $this->Conn->Query($sql); + } } /** @@ -2609,7 +2622,7 @@ if ( !$this->Application->isAdmin ) { $file_helper =& $this->Application->recallObject('FileHelper'); /* @var $file_helper FileHelper */ - + $file_helper->createItemFiles($event->Prefix, true); // create image fields $file_helper->createItemFiles($event->Prefix, false); // create file fields }