like сортировка по максимальному совпадению.

mar_a

Новичок
like сортировка по максимальному совпадению.

Есть самый простой запрос (например)
select x.name from table as x where x.name like "%$search%";
Результат этого запроса незаставит себя ждать и отобразит полный перечень поля х.name
удовлетворяющий условию.

Необходимо отсортировать результаты по максимальному совпадению как фразы так и количества фраз.

Напрмер в БД поле name содержит
Sony - 1
Sony PSP One
Sony PSP -3
Sony One
Ericsson Two
Sony Ericsson One
Sony Ericsson Two

При $search = on
Необходимо что-бы полученный результат запроса отсортировал
по максимальному кол-ву совпадений встречающихся в поле x.name
А именно:

Son y Ericsson Оne ///3 совпадения
Sony One /// 2 совпадения - но искомые комбинации на минимальном удалении друг от друга , поэтому ранжируется выше нежели остальные
Sony PSP one /// 2 совпадения
Son y Ericsson Two /// 2 совпадения
Sony - 1 ///1совпадение
Sony PSP -3 ///1совпадение
Ericsson Two ///1 совпадение но оно дальше от начала строки , следовательно имеет меньший приоритет

Вопрос собственно как наложить условие сортировки в SQL запрос дабы добится нужного эффекта?


Далее усложняю задачу
При $search1 = Sony
$search2=Ericsson
select x.name from table as x where x.name like "%$search1%" OR x.name like "%$search2%";

Необходимо добиться результата:
Sony Ericsson One ///максимально благоприятное нахождение
Sony Ericsson Two
И далее с одним совпадением из 2-х возможных
Sony - 1
Sony PSP One
Sony PSP -3
Sony One
Ericsson Two

Вопрос как составить запрос? (или серию запросов).
Отдельное спасибо за Ваши предложения об улучшении (быть может я не вижу банального).
 

mar_a

Новичок
Искренне благодарю...
Право не знал об этом в MySql

-~{}~ 02.07.10 10:37:

Теперь вопрос уже более конкретный
Испольую Конструкция MATCH-AGAINST уже успел поиграться как с NATURAL LANGUAGE MODE так и с BOOLEAN MODE.
Возникает вопрос по реливантности
скажем для моего случая
SELECT *,
MATCH (name) AGAINST ('$search' IN BOOLEAN MODE) as REL
FROM `table`
WHERE MATCH (name) AGAINST ('$search' IN BOOLEAN MODE)
ORDER BY REL;

И для второго случая:
SELECT *,
MATCH (name) AGAINST ('$search1$search2' IN BOOLEAN MODE) as REL
FROM `table`
WHERE MATCH (name) AGAINST ('$search1$search2 ' IN BOOLEAN MODE)
ORDER BY REL;
///Естественно поле name type= text и имеет одноименный ключ fulltext

самое странное оказывается для меня, это то ,что максимальное совпадение казалось-бы очевидное становится с релевантностью 1 как и для остальных случаев...

Может где подводный камень (да статью перечитал несколько раз).
Обязательно ли использовать 2 поля (как в примере FAQ) для более-менее качественого получения релевантности?

Еще-раз спасибо за помощь.
 

mar_a

Новичок
Пример :
--
-- Структура таблицы `table`
--

CREATE TABLE `table` (
`id` smallint(3) unsigned zerofill NOT NULL auto_increment,
`name` text NOT NULL,
`note` text,
PRIMARY KEY (`id`),
FULLTEXT KEY `name` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=cp1251 AUTO_INCREMENT=9 ;

--
-- Дамп данных таблицы `table`
--

INSERT INTO `table` VALUES (001, 'Son y Ericsson Оne', NULL);
INSERT INTO `table` VALUES (002, 'Sony - 1', NULL);
INSERT INTO `table` VALUES (003, 'Sony PSP One', NULL);
INSERT INTO `table` VALUES (004, 'Sony PSP -3', NULL);
INSERT INTO `table` VALUES (005, 'Sony One', NULL);
INSERT INTO `table` VALUES (006, 'Ericsson Two', NULL);
INSERT INTO `table` VALUES (007, 'Sony Ericsson Two', NULL);
INSERT INTO `table` VALUES (008, 'SonyEricsson Free device', NULL);

Пример запроса:
SELECT * ,
MATCH (name) AGAINST ('sony eric' IN BOOLEAN MODE ) AS REL
FROM `table` WHERE MATCH (name) AGAINST ('sony eric' IN BOOLEAN
MODE ) ORDER BY REL;

результат:
id name note REL
002 Sony - 1 NULL 1
003 Sony PSP One NULL 1
004 Sony PSP -3 NULL 1
005 Sony One NULL 1
007 Sony Ericsson Two NULL 1

Должно было-бы быть иначе индекс REL для Sony Ericsson Two должен быть отличным от остальных , по моему более 1 ...
 

prolis

Новичок
1. Почему "IN BOOLEAN MODE"?
2. "IN BOOLEAN MODE" результат для двух слов: 0- нет совпадений, 1 - одно слово нашлось, 2 - оба слова.
В вашем случае "eric" нет такого слова в данных, поэтому везде результат 1.
3. В "IN BOOLEAN MODE" можно использовать модификаторы +-><()`*. В вашем случае: "eric*"
4. Для отображения дробного коэффициента в первом MATCH уберите "IN BOOLEAN MODE"
 

mar_a

Новичок
Отвечаю
1,2) IN BOOLEAN MODE - это просто последний из запросов.
На самом деле пробовал как NATURAL LANGUAGE MODE - это по умолчанию (без указания режима) и второй случай BOOLEAN MODE - на сколько я понял из описания меняется логика режима поиска сопоставления результатов релевантности. Поэтому немного удивлен...Eric - слово есть оно входит в состав Sony Ericsson Two (по крайней мере мне так показалось).
Да увидел надо было Eric* - согласен , тупанул.
3) С модификаторами также пробовал , но видимо не предал должного значения (честно пробовал +eric) но результат аналогичен. Попробую внимательнее...
4) Да, да конечно если уберу то режим будет NATURAL LANGUAGE MODE - там действительно дробные коэф.

Спасибо переиначу , допишу...

-~{}~ 02.07.10 17:04:

Все получилось , огромное спасибо за коментарии и собое желание помочь.
 
Сверху