|
|
|
| Вообщем есть таблица в ней - 15 тысяч наименований. У нас есть какой-то тектс на 50-100 слов нужно найти совпадающие слова с наименованиями..
1) какой можно сделать оптимизированный алгоритм поиска, что бы это дело вертелось быстрее?
2) Вообще ставит меня в тупик - кужно найти слова похожите на те что есть в таблице - тоесть написанные с ошибкой, ошибка - одна неверная буква.. тут я вообще стопорюсь... видимо получаем массив таблицы, потом с помощью регулярки заменяем в слове поочереди каждую букву на '.' сравниваем с массивом? Сколько же это тогда будет все обрабатываться- представить сложно. | |
|
|
|
|
|
|
|
для: Гость
(09.04.2008 в 20:03)
| | По первому пункту - думаю. проще всего по каждому слову отдельно делать полнотекстовый поиск средствами БД. | |
|
|
|
|
|
|
|
для: Гость
(09.04.2008 в 20:03)
| | задачка довольно интересная..
я бы не стал делать такое по принципу "запускается каждый раз при загрузке страницы", а сделал бы однократный запуск с записью результата..
думаю здесь будет уместно использовать полнотесктовый поиск
делаем запрос (предполагается что полнотекстовый индекс уже сделан)
select `id` from `naimenovaniya` where match(title) against('our big text about acer notebook')
|
в итоге получаем ID-шки позиций, заголовки которых найдены в нашем тексте
далее возможны 2 варианта:
либо записать эти ID-шки куда то, и при каждом формировании страницы выбирать все title по этим ID-шкам и выделять совпадения в тексте,
либо изменить 1 раз текст и сохранить его копию
вот как то так
а с п.2 действительно придется подумать.. | |
|
|
|
|
|
|
|
для: Гость
(09.04.2008 в 20:03)
| | Сделал бы как Киналь :) Разбить текст на слова (регулярными выражениями или простым explode(); ), а потом цикл и полнотекстовый поиск ))) | |
|
|
|
|
|
|
|
для: DEM
(09.04.2008 в 21:53)
| | зачем разбивать?
mysql> select col1 from shit where match(col1) against ('our big text about Acer note vs acorp');
+-----------+
| col1 |
+-----------+
| acer W32 |
| acer W32 |
| acer W32 |
| acorp GTX |
| acorp GTX |
| acorp GTX |
| acorp GTX |
+-----------+
7 rows in set (0.01 sec)
|
как видишь, находятся заголовки, в которых любое слово встречено в заданном тексте..
а если, как ты говоришь, разбить по словам, то зачем тогда полнотекстовый поиск? хватит и like '%word%', только вот количество запросов в твоем случае будет 50-100 (по кол-ву слов в тексте), а в моем - 1 | |
|
|
|
|
|
|
|
для: mechanic
(09.04.2008 в 22:13)
| | Недавно на форуме была такая тема, посмотрите man на PHP-функцию:
levenshtein() --Вычисляет расстояние Левенштейна между двумя строками.
Расстояние Левенштейна - это минимальное количество вставок, замен и удалений символов, необходимое для преобразования str1 в str2.
Возможно это то, что вам надо. | |
|
|
|
|
|
|
|
для: Гость
(09.04.2008 в 20:03)
| | Всем спасибо. Первый этап прошел, теперь загвоздка. Заключается в том что имена в таблице могут состоять из двух и даже из трех слов.
Итак таблица table - id|name
в ней три записи
1|test
2|play
3|play test
Я делаю запрос
SELECT `id`
FROM table
WHERE MATCH (
name
)
AGAINST (
'play test'
IN BOOLEAN
MODE
)
LIMIT 0 , 30
|
И получаю два ключа - 1 и 3-тий. Вопрос - как бы получить в этом случае только третий ключ?
PS: только что заметил что порядок слов в AGAINST не имеет значения, впрочем логично, тоесть если у нас в начале текста встретится play а под конец где-то далеко test то все равно нам вернется id 3, впрочем это вполне решаемо, неприятно другое - Кроме того таким образом он не ищет нэймы из трех слов. Есть какое--то еще решение? myAdmin предложил такой запрос:
SQL-запрос:
SELECT *
FROM `table`
WHERE (
`name` LIKE '%play%'
)
OR (
`name` LIKE '%test%'
)
LIMIT 0 , 30
|
Но он гораздо более длительный по сравнению с первым вариантом если слов не два, а под 200-300. Но с помошью него как раз возмжоно решить проблему "с тремя словами"... | |
|
|
|
|
|
|
|
для: Гость
(14.04.2008 в 19:06)
| | идей нет? Нехочется делать "медленный вариант" но видимо придется использовать его | |
|
|
|