<
  • Главная
Статьи

OpenNET: стаття - Повнотекстовий пошук в MySQL на PHP (mysql search php web)

  1. OpenNET: стаття - Повнотекстовий пошук в MySQL на PHP (mysql search php web)
  2. OpenNET: стаття - Повнотекстовий пошук в MySQL на PHP (mysql search php web)
  3. OpenNET: стаття - Повнотекстовий пошук в MySQL на PHP (mysql search php web)

OpenNET: стаття - Повнотекстовий пошук в MySQL на PHP (mysql search php web)

Повнотекстовий пошук в MySQL на PHP (mysql search php web)


Ключові слова: mysql , search , php , web , ( знайти схожі документи )
From: Дмитро Лебедєв, Олег Юсов Newsgroups: http://detail.phpclub.net/ Date: Mon, 20 Sep 2004 18:21:07 +0000 (UTC) Subject: Повнотекстовий пошук в MySQL на PHP Оригінал: http://detail.phpclub.net/article/mysql_search Безпечний і зручний пошук в mySQL Дмитро Лебедєв 2000-12-18 Коротка довідка по реалізації пошуку: Обробка рядки, вирізання службових символів, складання запиту до бази, логіка, посторінковий висновок, релевантність. 1. Загальні відомості 2. Коротко про релевантності 3. Вправи c релевантність 4. Продолеженіе розпочатого Частина 1: Загальні відомості Обробка рядки Насамперед треба порізати ручками рядок. $ Search = substr ($ search, 0, 64); 64 символів користувачеві буде досить для пошуку. Тепер розпеченим залізом випалимо все "ненормальні" символи. $ Search = preg_replace ( "/ [^ \ w \ x7F- \ xFF \ s] /", "", $ search); За ідеєю, не можна давати користувачеві можливості шукати по занадто коротким словами - крім усього іншого, це сильно завантажує сервер. Отже, дозволимо шукати тільки зі слів, які довше двох букв (якщо обмеження більше, треба замінити "{1,2}" на "{1, к-ть символів}"). $ Good = trim (preg_replace ( "/ \ s (\ S {1,2}) \ s /", "", ereg_replace ( "+", "", "$ search"))); А після заміни поганих слів - треба стиснути подвійні пробіли (вони були зроблені спеціально для коректного пошуку коротких слів). $ Good = ereg_eplace ( "+", "", $ good); Логіка Припустимо, ми хочемо надати користувачеві можливість вибирати логіку пошуку - шукати все слова або тільки одне з декількох. Якщо ви хочете зробити як в [27] Яндексі - два амперсанта означають "І" (слово1 && слово2 && слово3) або якось ще, то я не порадник. Шаманство з рядками на невеликому сайті imho не виправдовує витраченого часу. Тому форму для пошуку малюємо так: <form name = "some"> <input type = text name = "stroka"> <select name = "logic"> <option value = "OR"> шукати будь-яке з слів <option value = "AND"> шукати всі слова </ select> </ form> А в пошуковому скрипті зайвий раз перевіряємо, що користувач ввів: if (($ logic! = "AND") && ($ logic! = "OR")) $ logic = "OR"; Як буде використовуватися логіка - нижче. Статистика пошуку Непогано буде відразу інформувати користувача, скільки він знайшов рядків таблиці. Для цього робиться додатковий запит до бази: $ query = "SELECT id FROM table WHERE field LIKE '%". str_replace ( "", "% 'OR field LIKE'%", $ good). "% '"; Для статистики по окремим словами можна зробити наступне: $ word = explode ( "", $ search); while (list ($ k, $ v) = each ($ word)) {if (strlen ($ v)> 2) $ stat [] = "$ v:". mysql_num_rows (mysql_query ( "SELECT id FROM table WHERE field LIKE '% $ v%'")); else $ stat [] = "$ v: <font color = # cc0000> короткий </ font>"; }; $ Word_stats = "Статистика слів:". implode ( "", $ stat). "<br>"; unset ($ stat); Посторінковий вивід результатів Ну, коли у нас є макет для пошуку і кількість рядків результату пошуку, зробити посторінковий пошук - справа нехитра. Перевіряємо змінну $ page (незгірш від 0, не більше $ results_amount / $ rows_in_page) .В запит, який підраховує кількість рядків (дивись вище), пишемо потрібні нам поля та поля для сортування. А потім дописуємо if ($ page == 0) $ request. = "LIMIT $ rows_in_page"; else $ request. = "LIMIT". $ Page * $ rows_in_page. ",". $ Rows_in_page; (Синтаксис: LIMIT <кількість рядків> або LIMIT <кількість рядків відступу "," кількість рядків>) В результаті виконання подібного запиту ми отримаємо саме ті самі рядки, які треба виводити на страніце.Для навігації можна або малювати посилання на наступну і попередню сторінки, або, що складніше, робити панель навігації на кілька сторінок. if ($ page> 0) print ( "<a href=search.php?search=". rawurlencode($good). "&page=". ($page-1). "> попередня сторінка </a>") ; if ($ page <$ results_amount / $ rows_in_page) print ( "<a href = search.php? search =". rawurlencode ($ good). "& page =". ($ page + 1). "> наступна сторінка </ a> "); Підсвічування Щоб підсвічувати світлом або жирним шрифтом шукані слова в тексті, треба зробити всього лише наступне: $ highlight = str_replace ( "", "|", $ good); Прогалини (а вони у нас між словами стоять поодинці, і ніде подвійний пробіл не зустрічається, до того ж з кінців рядка ми їх теж вирізали) досить замінити на вертикальну риску - роздільник варіантів в регулярних виразах. "Погані" слова ми не підсвічується, тому що в основі їх не шукаємо :). У коді, який виводить текст пишемо: $ row [ "text"] = ereg_replace ($ highlight, "<font color = # cc0000> \\ 0 </ font>", $ row [ "text"]); Після написання випуску я кинувся, було, писати і собі "підсвічування". Не тут то було! У мене в тексті зустрічаються теги HTML, тому довелося багато подумати ... Вийшла ось така річ (рядок зі словами для підсвічування є): $ text = eregi_replace ( "> ([^ <] *) ($ words)", "> \\ 1 <font color = # cc0000> \\ 2 </ font> ", $ text); Доводиться дивитися, немає в тезі це слово. Однак тут постає проблема ресурсоємності такої заміни (мій K6-266 над текстом в 5 кілобайт думав цілих сім секунд). Сумно. Підсумок Застосовуючи такі прийоми, можна, по-перше, обмежити свободу дій користувача і не дати йому а) дізнатися програмну структуру сайту б) викликати перевантаження сервера (наприклад, відправивши мегабайт тексту, що складається зі слів довжиною в три букви (фраза вийшла двозначна, але переписувати Не буду :), щоб скрипт 250 тисяч разів лазив в базу) в) побачити повідомлення про помилку в результаті попадання в рядок спецсимволов мови запитів. По-друге, деякий зручність для користувача - посторінковий вивід і підсвічування. Пам'ятається в статті "Безпечний і зручний пошук" була така фраза: Частина 2. Коротко про релевантності Олег Юсов Для виведення результатів пошуку за релевантністю необхідно: * Необхідні поля VARCHAR, або будь-які з різновидів полів TEXT (SMALLTEXT, MEDIUMTEXT і т.п.) зробити ключами FULLTEXT: ALTER TABLE table ADD FULLTEXT (field) * Далі - ще простіше: $ query = "SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table ORDER BY relev DESC" Далі можна навішувати всякі LIMIT ' и та інше для зручного виведення. Нотатки: * За замовчуванням встановлено пошук слів, що містять не менше 4 символів. Правиться установкою #define MIN_WORD_LEN 4 в исходнике ft_static.c, хоча на мій погляд правити це не потрібно. * Недоступні символи% в пошуковій фразі, слова в пошуковій фразі Парс з використанням списку разделетелей. * Список роздільників слів правиться в исходнике ft_static.c. * Необхідно мінімум десяток записів в таблиці для початку обчислення релевантності. * Не можна поле relev використовувати в Клаузе WHERE: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE relev> 0 ORDER BY relev DESC хоча можна: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE MATCH field AGAINST ( '$ searchwords')> 0 ORDER BY relev DESC * Швидкість досить висока - навіть в деяких випадках швидше like пошуку * Все вищесказане працює починаючи з версії MySQL 3.23.23 При створенні індексів FULLTEXT по декількох полях можливі 2 варіанти: CREATE TABLE table (field1 VARCHAR (255), field2 TEXT, FULLTEXT (field1, field2)) CREATE TABLE table (field1 VARCHAR (255), field2 TEXT, FULLTEXT (field1), FULLTEXT (field2)) В першому випадку можливий запит: SELECT *, MATCH field1, field2 AGAINST ( '$ searchwords') as relev FROM table ORDER BY relev DESC релевантність обчислюється у всіх полів відразу. У другому випадку такий запит видасть помилку. Тут обчислюємо релевантність наступним чином: SELECT *, MATCH field1 AGAINST ( '$ searchwords') + MATCH field2 AGAINST ( '$ searchwords') as relev FROM table ORDER BY relev DESC Другий варіант трохи складніше в запитах, однак, на мій погляд краще, тому збільшується гнучкість пошуку - до кожного з полів можна задати, наприклад, коефіцієнт значущості і при підсумовуванні релевантні полів множити їх на цей коефіцієнт. Пошукова фраза буде "більше" шукатися в полях з великим коефіцієнтом. Наприклад, якщо ми робимо пошук по проіндексованих сторінок каталогу ресурсів, то поле імені сторінки зазвичай задають з великим коефіцієнтом, ніж поля мета-тегів описів або ключових слів. Частина 3: Вправи c релевантностью Спочатку як додати FULLTEXT-індекс: mysql> alter table articlea add fulltext (ztext); ERROR 1073: BLOB column 'ztext' can not be used in key specification with the used table type mysql> alter table articlea type = myisam; Query OK, 36 rows affected (0.60 sec) Records: 36 Duplicates: 0 Warnings: 0 mysql> alter table articlea add fulltext (ztext); Query OK, 36 rows affected (10.00 sec) Records: 36 Duplicates: 0 Warnings: 0 Текстові індекси можна робити тільки в таблицях типу MyISAM. Тексти беруться з таблиці і скидаються в файл індексу, і зростає обсяг бази. З приводу запитів. Не можна поле relev використовувати в Клаузе WHERE: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE relev> 0 ORDER BY relev DESC хоча можна: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE MATCH field AGAINST ( '$ searchwords')> 0 ORDER BY relev DESC Обчислення поле, звичайно ж, не можна використовувати в WHERE за всіма правилами синтаксису, але можна використовувати в HAVING: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table HAVING relev> 0 ORDER BY relev DESC Пошук через MATCH, як писав Олег, робиться тільки по слову цілком. ... Втім, за релевантністю можна тільки сортувати, а вибирати по LIKE (це, звичайно, позначиться на продуктивності, навіть не знаю, наскільки). Прибираємо умова "relev> 0", залишаємо сортування. Усе інше, як і раніше - рубаємо отриманий рядок і перетворюємо в запит з декількома операторами LIKE: SELECT *, MATCH field AGAINST ( '$ searchwords') AS relev FROM table WHERE field LIKE '% $ word1%' OR field LIKE '% $ word2% 'ORDER BY relev DESC, datefield DESC Частина 4: Продолеженіе розпочатого Продовжую розпочату у вересні тему пошуку з сортуванням за релевантністю в базі MySQL. MySQL пропонує в останніх версіях бази даних використовувати для повнотекстового пошуку індексацію FULLTEXT і конструкцію MATCH field AGAINST. Однак не на всіх серверах стоїть остання версія MySQL, і не всі хостинг-провайдери хочуть оновлювати софт з міркувань надійності системи. Свого часу я припускав, що пошук з сортуванням за релевантністю треба буде робити в кілька запитів, і, отже, краще зовсім не братися за це. Думки, що релевантність можна підраховувати в самому запиті віддалено мене відвідували, але я боявся навіть уявити таку конструкцію. Однак же, працівник однієї з сайтобудівна фірм Н-ска похвалився мені системою пошуку, яку вони застосовують на своїх сайтах. Я точно не запам'ятав запит, спробую так відтворити його: SELECT title, date_format (material_date, '% e.% C.% Y') AS date1, IF (text like '% word1 word2 word3%', 3 * 10, 0) + IF (text LIKE '% word1%', 9, 0) + IF (text LIKE '% word2%', 9, 0) + IF (text LIKE '% word3%', 9, 0) AS relevance FROM table WHERE text LIKE '% word1%' OR text LIKE '% word2%' OR text LIKE '% word3%' ORDER BY relevance DESC, material_date DESC Жахливо виглядає, але працює навіть на старих версіях MySQL. Спробував порівняти швидкість роботи з ось таким запитом: SELECT title, date_format (material_date, '% e.% C.% Y') AS date1, MATCH text AGAINST ( 'word1 word2 word3') AS relevance FROM table WHERE text LIKE '% word1 % 'OR text LIKE'% word2% 'OR text LIKE'% word3% 'ORDER BY relevance DESC, material_date DESC в середньому швидкість універсального запиту в два рази менше, ніж використовує нові конструкції. Що цілком логічно - чим більше універсальність, тим більше ресурсомісткість. Спробуємо побудувати такий запит автоматично. Відрізаємо довгий рядок, а так само всі неправильні символи і короткі слова. Малюємо запит. $ Query = "SELECT title, date_format (material_date, '% e.% C.% Y') AS date1, IF (text like '%". $ Good_words. "%',". (Substr_count ($ good_words, "" ) + 1). "* 10, 0) + IF (text LIKE '%". str_replace ( "", "%', 9, 0) + IF (text LIKE '%", $ good_words). "%', 9, 0) AS relevance FROM table WHERE text LIKE '% ". str_replace ( "", "% 'OR text LIKE'%", $ good_words). "% 'ORDER BY relevance DESC, material_date DESC"; Не дуже-то складно. Для надійності і захисту від флуду можна обмежити кількість слів у запиті. Деякі доповнення до колишніх публікацій Загальна кількість знайдених рядків в таблиці. Для виведення результатів пошуку, зрозуміло, треба користуватися оператором LIMIT (щоб не писати кожен раз формування цього параметра, користуйтеся готовими функціями). Якщо ніяких операцій угруповання в запиті не робиться, краще підрахувати кількість рядків відразу в запиті - COUNT (*), а не через функцію php mysql_num_rows (). Можете перевірити на великих таблицях. Якщо виробляються групові операції, робимо запит з COUNT (DISTINCT ()), але без GROUP BY. Підсвічування. Якщо в текстах не буває html-тегів, жити простіше $ text = preg_replace ( "/ word1 | word2 | word3 / i", "<b> \\ 0 </ b>", $ text); Якщо в тексті теги використовуються, то є три варіанти а) не робити підсвічування б) оскільки теги користувач не бачить (хіба що дуже цікавий користувач), то можна зробити поле індексу, в якому не буде тегів а символи [^ \ w \ x7F- \ xFF \ s] будуть замінені на прогалини (саме ці символи вирізаються з пошукового рядка на самому початку, так що пошук по них не проводиться). Пошук і підсвічування в такому випадку зробити саме за індексом. в) робити підсвічування тексту зі звичайного поля, попередньо вирізавши теги функцією srip_tags (). Повна версія пошукового коду, як завжди, в списку файлів. Пошук з розбивкою на сторінки (Дмитро Бородін) http://php.spb.ru/mysql/limit.html


  • 1.3 , Ігор (??), 4:02, 19/01/2008 [ відповісти ] [ +++ ] [ · · · ]
+ / - Повнотекстовий пошук в MySQL на PHP (mys, LineDir, 00:10:53, 02/12/2007 [відповісти] (2)
на рахунок подсветкі..хотел б подивитися як вона у тебе працює ... маячня

Не знаю чому це маячня, у мене все працює нормально.

  • 1.6 , Юрій (??), 19:53, 11/03/2008 [ відповісти ] [ +++ ] [ · · · ]
+ / - Под'ебка це, а не повнотекстовий пошук. Навіть Гугл робить це краще - а він зовсім не шедевр. Парсер пошукових рядків повинен бути повноцінним, а до речі - що робити, якщо треба індексувати НЕ гіпертекстові або плоскі файли? Як щодо фільтрації? Песта?
  • 1.7 , KRoT (?), 00:04, 01/05/2008 [ відповісти ] [ +++ ] [ · · · ]
+ / - Ось напрацювання оптимальної системи пошуку, думаю, стаття незабаром буде дописана, але додумати і так можна ...
http://www.xbrain.ru/content/view/41/10/
> Под'ебка це, а не повнотекстовий пошук

Скрипти Дмитра Лебедєва ніколи не були "под'ебка"! А якщо у когось не вистачає розуму (до / пере) робити скрипт - ДО-СВИ-ДА-НИ-Я!

  • 1.11 , Стас (??), 13:29 20/05/2010 [ відповісти ] [ +++ ] [ · · · ]
+ / - Та це взагалі повна маячня. Для повнотекстового пошуку давно є спеціалізовані речі - наприклад Sphinx
  • 1.18 , Павло (??), 11:32, 10/12/2011 [ відповісти ] [ +++ ] [ · · · ]
+ / - Дякую автору! Гарна стаття .. дізнався для себе трохи новенького і корисного :)
Не можу зрозуміти одного чому у Вас проблема з слів оточених тегами. Для цього є strip_tags

На виході все чисто і красиво :)



Додати коментар

Спонсори:

Хостинг:



OpenNET: стаття - Повнотекстовий пошук в MySQL на PHP (mysql search php web)

Повнотекстовий пошук в MySQL на PHP (mysql search php web)


Ключові слова: mysql , search , php , web , ( знайти схожі документи )
From: Дмитро Лебедєв, Олег Юсов Newsgroups: http://detail.phpclub.net/ Date: Mon, 20 Sep 2004 18:21:07 +0000 (UTC) Subject: Повнотекстовий пошук в MySQL на PHP Оригінал: http://detail.phpclub.net/article/mysql_search Безпечний і зручний пошук в mySQL Дмитро Лебедєв 2000-12-18 Коротка довідка по реалізації пошуку: Обробка рядки, вирізання службових символів, складання запиту до бази, логіка, посторінковий висновок, релевантність. 1. Загальні відомості 2. Коротко про релевантності 3. Вправи c релевантність 4. Продолеженіе розпочатого Частина 1: Загальні відомості Обробка рядки Насамперед треба порізати ручками рядок. $ Search = substr ($ search, 0, 64); 64 символів користувачеві буде досить для пошуку. Тепер розпеченим залізом випалимо все "ненормальні" символи. $ Search = preg_replace ( "/ [^ \ w \ x7F- \ xFF \ s] /", "", $ search); За ідеєю, не можна давати користувачеві можливості шукати по занадто коротким словами - крім усього іншого, це сильно завантажує сервер. Отже, дозволимо шукати тільки зі слів, які довше двох букв (якщо обмеження більше, треба замінити "{1,2}" на "{1, к-ть символів}"). $ Good = trim (preg_replace ( "/ \ s (\ S {1,2}) \ s /", "", ereg_replace ( "+", "", "$ search"))); А після заміни поганих слів - треба стиснути подвійні пробіли (вони були зроблені спеціально для коректного пошуку коротких слів). $ Good = ereg_eplace ( "+", "", $ good); Логіка Припустимо, ми хочемо надати користувачеві можливість вибирати логіку пошуку - шукати все слова або тільки одне з декількох. Якщо ви хочете зробити як в [27] Яндексі - два амперсанта означають "І" (слово1 && слово2 && слово3) або якось ще, то я не порадник. Шаманство з рядками на невеликому сайті imho не виправдовує витраченого часу. Тому форму для пошуку малюємо так: <form name = "some"> <input type = text name = "stroka"> <select name = "logic"> <option value = "OR"> шукати будь-яке з слів <option value = "AND"> шукати всі слова </ select> </ form> А в пошуковому скрипті зайвий раз перевіряємо, що користувач ввів: if (($ logic! = "AND") && ($ logic! = "OR")) $ logic = "OR"; Як буде використовуватися логіка - нижче. Статистика пошуку Непогано буде відразу інформувати користувача, скільки він знайшов рядків таблиці. Для цього робиться додатковий запит до бази: $ query = "SELECT id FROM table WHERE field LIKE '%". str_replace ( "", "% 'OR field LIKE'%", $ good). "% '"; Для статистики по окремим словами можна зробити наступне: $ word = explode ( "", $ search); while (list ($ k, $ v) = each ($ word)) {if (strlen ($ v)> 2) $ stat [] = "$ v:". mysql_num_rows (mysql_query ( "SELECT id FROM table WHERE field LIKE '% $ v%'")); else $ stat [] = "$ v: <font color = # cc0000> короткий </ font>"; }; $ Word_stats = "Статистика слів:". implode ( "", $ stat). "<br>"; unset ($ stat); Посторінковий вивід результатів Ну, коли у нас є макет для пошуку і кількість рядків результату пошуку, зробити посторінковий пошук - справа нехитра. Перевіряємо змінну $ page (незгірш від 0, не більше $ results_amount / $ rows_in_page) .В запит, який підраховує кількість рядків (дивись вище), пишемо потрібні нам поля та поля для сортування. А потім дописуємо if ($ page == 0) $ request. = "LIMIT $ rows_in_page"; else $ request. = "LIMIT". $ Page * $ rows_in_page. ",". $ Rows_in_page; (Синтаксис: LIMIT <кількість рядків> або LIMIT <кількість рядків відступу "," кількість рядків>) В результаті виконання подібного запиту ми отримаємо саме ті самі рядки, які треба виводити на страніце.Для навігації можна або малювати посилання на наступну і попередню сторінки, або, що складніше, робити панель навігації на кілька сторінок. if ($ page> 0) print ( "<a href=search.php?search=". rawurlencode($good). "&page=". ($page-1). "> попередня сторінка </a>") ; if ($ page <$ results_amount / $ rows_in_page) print ( "<a href = search.php? search =". rawurlencode ($ good). "& page =". ($ page + 1). "> наступна сторінка </ a> "); Підсвічування Щоб підсвічувати світлом або жирним шрифтом шукані слова в тексті, треба зробити всього лише наступне: $ highlight = str_replace ( "", "|", $ good); Прогалини (а вони у нас між словами стоять поодинці, і ніде подвійний пробіл не зустрічається, до того ж з кінців рядка ми їх теж вирізали) досить замінити на вертикальну риску - роздільник варіантів в регулярних виразах. "Погані" слова ми не підсвічується, тому що в основі їх не шукаємо :). У коді, який виводить текст пишемо: $ row [ "text"] = ereg_replace ($ highlight, "<font color = # cc0000> \\ 0 </ font>", $ row [ "text"]); Після написання випуску я кинувся, було, писати і собі "підсвічування". Не тут то було! У мене в тексті зустрічаються теги HTML, тому довелося багато подумати ... Вийшла ось така річ (рядок зі словами для підсвічування є): $ text = eregi_replace ( "> ([^ <] *) ($ words)", "> \\ 1 <font color = # cc0000> \\ 2 </ font> ", $ text); Доводиться дивитися, немає в тезі це слово. Однак тут постає проблема ресурсоємності такої заміни (мій K6-266 над текстом в 5 кілобайт думав цілих сім секунд). Сумно. Підсумок Застосовуючи такі прийоми, можна, по-перше, обмежити свободу дій користувача і не дати йому а) дізнатися програмну структуру сайту б) викликати перевантаження сервера (наприклад, відправивши мегабайт тексту, що складається зі слів довжиною в три букви (фраза вийшла двозначна, але переписувати Не буду :), щоб скрипт 250 тисяч разів лазив в базу) в) побачити повідомлення про помилку в результаті попадання в рядок спецсимволов мови запитів. По-друге, деякий зручність для користувача - посторінковий вивід і підсвічування. Пам'ятається в статті "Безпечний і зручний пошук" була така фраза: Частина 2. Коротко про релевантності Олег Юсов Для виведення результатів пошуку за релевантністю необхідно: * Необхідні поля VARCHAR, або будь-які з різновидів полів TEXT (SMALLTEXT, MEDIUMTEXT і т.п.) зробити ключами FULLTEXT: ALTER TABLE table ADD FULLTEXT (field) * Далі - ще простіше: $ query = "SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table ORDER BY relev DESC" Далі можна навішувати всякі LIMIT ' и та інше для зручного виведення. Нотатки: * За замовчуванням встановлено пошук слів, що містять не менше 4 символів. Правиться установкою #define MIN_WORD_LEN 4 в исходнике ft_static.c, хоча на мій погляд правити це не потрібно. * Недоступні символи% в пошуковій фразі, слова в пошуковій фразі Парс з використанням списку разделетелей. * Список роздільників слів правиться в исходнике ft_static.c. * Необхідно мінімум десяток записів в таблиці для початку обчислення релевантності. * Не можна поле relev використовувати в Клаузе WHERE: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE relev> 0 ORDER BY relev DESC хоча можна: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE MATCH field AGAINST ( '$ searchwords')> 0 ORDER BY relev DESC * Швидкість досить висока - навіть в деяких випадках швидше like пошуку * Все вищесказане працює починаючи з версії MySQL 3.23.23 При створенні індексів FULLTEXT по декількох полях можливі 2 варіанти: CREATE TABLE table (field1 VARCHAR (255), field2 TEXT, FULLTEXT (field1, field2)) CREATE TABLE table (field1 VARCHAR (255), field2 TEXT, FULLTEXT (field1), FULLTEXT (field2)) В першому випадку можливий запит: SELECT *, MATCH field1, field2 AGAINST ( '$ searchwords') as relev FROM table ORDER BY relev DESC релевантність обчислюється у всіх полів відразу. У другому випадку такий запит видасть помилку. Тут обчислюємо релевантність наступним чином: SELECT *, MATCH field1 AGAINST ( '$ searchwords') + MATCH field2 AGAINST ( '$ searchwords') as relev FROM table ORDER BY relev DESC Другий варіант трохи складніше в запитах, однак, на мій погляд краще, тому збільшується гнучкість пошуку - до кожного з полів можна задати, наприклад, коефіцієнт значущості і при підсумовуванні релевантні полів множити їх на цей коефіцієнт. Пошукова фраза буде "більше" шукатися в полях з великим коефіцієнтом. Наприклад, якщо ми робимо пошук по проіндексованих сторінок каталогу ресурсів, то поле імені сторінки зазвичай задають з великим коефіцієнтом, ніж поля мета-тегів описів або ключових слів. Частина 3: Вправи c релевантностью Спочатку як додати FULLTEXT-індекс: mysql> alter table articlea add fulltext (ztext); ERROR 1073: BLOB column 'ztext' can not be used in key specification with the used table type mysql> alter table articlea type = myisam; Query OK, 36 rows affected (0.60 sec) Records: 36 Duplicates: 0 Warnings: 0 mysql> alter table articlea add fulltext (ztext); Query OK, 36 rows affected (10.00 sec) Records: 36 Duplicates: 0 Warnings: 0 Текстові індекси можна робити тільки в таблицях типу MyISAM. Тексти беруться з таблиці і скидаються в файл індексу, і зростає обсяг бази. З приводу запитів. Не можна поле relev використовувати в Клаузе WHERE: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE relev> 0 ORDER BY relev DESC хоча можна: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE MATCH field AGAINST ( '$ searchwords')> 0 ORDER BY relev DESC Обчислення поле, звичайно ж, не можна використовувати в WHERE за всіма правилами синтаксису, але можна використовувати в HAVING: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table HAVING relev> 0 ORDER BY relev DESC Пошук через MATCH, як писав Олег, робиться тільки по слову цілком. ... Втім, за релевантністю можна тільки сортувати, а вибирати по LIKE (це, звичайно, позначиться на продуктивності, навіть не знаю, наскільки). Прибираємо умова "relev> 0", залишаємо сортування. Усе інше, як і раніше - рубаємо отриманий рядок і перетворюємо в запит з декількома операторами LIKE: SELECT *, MATCH field AGAINST ( '$ searchwords') AS relev FROM table WHERE field LIKE '% $ word1%' OR field LIKE '% $ word2% 'ORDER BY relev DESC, datefield DESC Частина 4: Продолеженіе розпочатого Продовжую розпочату у вересні тему пошуку з сортуванням за релевантністю в базі MySQL. MySQL пропонує в останніх версіях бази даних використовувати для повнотекстового пошуку індексацію FULLTEXT і конструкцію MATCH field AGAINST. Однак не на всіх серверах стоїть остання версія MySQL, і не всі хостинг-провайдери хочуть оновлювати софт з міркувань надійності системи. Свого часу я припускав, що пошук з сортуванням за релевантністю треба буде робити в кілька запитів, і, отже, краще зовсім не братися за це. Думки, що релевантність можна підраховувати в самому запиті віддалено мене відвідували, але я боявся навіть уявити таку конструкцію. Однак же, працівник однієї з сайтобудівна фірм Н-ска похвалився мені системою пошуку, яку вони застосовують на своїх сайтах. Я точно не запам'ятав запит, спробую так відтворити його: SELECT title, date_format (material_date, '% e.% C.% Y') AS date1, IF (text like '% word1 word2 word3%', 3 * 10, 0) + IF (text LIKE '% word1%', 9, 0) + IF (text LIKE '% word2%', 9, 0) + IF (text LIKE '% word3%', 9, 0) AS relevance FROM table WHERE text LIKE '% word1%' OR text LIKE '% word2%' OR text LIKE '% word3%' ORDER BY relevance DESC, material_date DESC Жахливо виглядає, але працює навіть на старих версіях MySQL. Спробував порівняти швидкість роботи з ось таким запитом: SELECT title, date_format (material_date, '% e.% C.% Y') AS date1, MATCH text AGAINST ( 'word1 word2 word3') AS relevance FROM table WHERE text LIKE '% word1 % 'OR text LIKE'% word2% 'OR text LIKE'% word3% 'ORDER BY relevance DESC, material_date DESC в середньому швидкість універсального запиту в два рази менше, ніж використовує нові конструкції. Що цілком логічно - чим більше універсальність, тим більше ресурсомісткість. Спробуємо побудувати такий запит автоматично. Відрізаємо довгий рядок, а так само всі неправильні символи і короткі слова. Малюємо запит. $ Query = "SELECT title, date_format (material_date, '% e.% C.% Y') AS date1, IF (text like '%". $ Good_words. "%',". (Substr_count ($ good_words, "" ) + 1). "* 10, 0) + IF (text LIKE '%". str_replace ( "", "%', 9, 0) + IF (text LIKE '%", $ good_words). "%', 9, 0) AS relevance FROM table WHERE text LIKE '% ". str_replace ( "", "% 'OR text LIKE'%", $ good_words). "% 'ORDER BY relevance DESC, material_date DESC"; Не дуже-то складно. Для надійності і захисту від флуду можна обмежити кількість слів у запиті. Деякі доповнення до колишніх публікацій Загальна кількість знайдених рядків в таблиці. Для виведення результатів пошуку, зрозуміло, треба користуватися оператором LIMIT (щоб не писати кожен раз формування цього параметра, користуйтеся готовими функціями). Якщо ніяких операцій угруповання в запиті не робиться, краще підрахувати кількість рядків відразу в запиті - COUNT (*), а не через функцію php mysql_num_rows (). Можете перевірити на великих таблицях. Якщо виробляються групові операції, робимо запит з COUNT (DISTINCT ()), але без GROUP BY. Підсвічування. Якщо в текстах не буває html-тегів, жити простіше $ text = preg_replace ( "/ word1 | word2 | word3 / i", "<b> \\ 0 </ b>", $ text); Якщо в тексті теги використовуються, то є три варіанти а) не робити підсвічування б) оскільки теги користувач не бачить (хіба що дуже цікавий користувач), то можна зробити поле індексу, в якому не буде тегів а символи [^ \ w \ x7F- \ xFF \ s] будуть замінені на прогалини (саме ці символи вирізаються з пошукового рядка на самому початку, так що пошук по них не проводиться). Пошук і підсвічування в такому випадку зробити саме за індексом. в) робити підсвічування тексту зі звичайного поля, попередньо вирізавши теги функцією srip_tags (). Повна версія пошукового коду, як завжди, в списку файлів. Пошук з розбивкою на сторінки (Дмитро Бородін) http://php.spb.ru/mysql/limit.html


  • 1.3 , Ігор (??), 4:02, 19/01/2008 [ відповісти ] [ +++ ] [ · · · ]
+ / - Повнотекстовий пошук в MySQL на PHP (mys, LineDir, 00:10:53, 02/12/2007 [відповісти] (2)
на рахунок подсветкі..хотел б подивитися як вона у тебе працює ... маячня

Не знаю чому це маячня, у мене все працює нормально.

  • 1.6 , Юрій (??), 19:53, 11/03/2008 [ відповісти ] [ +++ ] [ · · · ]
+ / - Под'ебка це, а не повнотекстовий пошук. Навіть Гугл робить це краще - а він зовсім не шедевр. Парсер пошукових рядків повинен бути повноцінним, а до речі - що робити, якщо треба індексувати НЕ гіпертекстові або плоскі файли? Як щодо фільтрації? Песта?
  • 1.7 , KRoT (?), 00:04, 01/05/2008 [ відповісти ] [ +++ ] [ · · · ]
+ / - Ось напрацювання оптимальної системи пошуку, думаю, стаття незабаром буде дописана, але додумати і так можна ...
http://www.xbrain.ru/content/view/41/10/
> Под'ебка це, а не повнотекстовий пошук

Скрипти Дмитра Лебедєва ніколи не були "под'ебка"! А якщо у когось не вистачає розуму (до / пере) робити скрипт - ДО-СВИ-ДА-НИ-Я!

  • 1.11 , Стас (??), 13:29 20/05/2010 [ відповісти ] [ +++ ] [ · · · ]
+ / - Та це взагалі повна маячня. Для повнотекстового пошуку давно є спеціалізовані речі - наприклад Sphinx
  • 1.18 , Павло (??), 11:32, 10/12/2011 [ відповісти ] [ +++ ] [ · · · ]
+ / - Дякую автору! Гарна стаття .. дізнався для себе трохи новенького і корисного :)
Не можу зрозуміти одного чому у Вас проблема з слів оточених тегами. Для цього є strip_tags

На виході все чисто і красиво :)



Додати коментар

Спонсори:

Хостинг:



OpenNET: стаття - Повнотекстовий пошук в MySQL на PHP (mysql search php web)

Повнотекстовий пошук в MySQL на PHP (mysql search php web)


Ключові слова: mysql , search , php , web , ( знайти схожі документи )
From: Дмитро Лебедєв, Олег Юсов Newsgroups: http://detail.phpclub.net/ Date: Mon, 20 Sep 2004 18:21:07 +0000 (UTC) Subject: Повнотекстовий пошук в MySQL на PHP Оригінал: http://detail.phpclub.net/article/mysql_search Безпечний і зручний пошук в mySQL Дмитро Лебедєв 2000-12-18 Коротка довідка по реалізації пошуку: Обробка рядки, вирізання службових символів, складання запиту до бази, логіка, посторінковий висновок, релевантність. 1. Загальні відомості 2. Коротко про релевантності 3. Вправи c релевантність 4. Продолеженіе розпочатого Частина 1: Загальні відомості Обробка рядки Насамперед треба порізати ручками рядок. $ Search = substr ($ search, 0, 64); 64 символів користувачеві буде досить для пошуку. Тепер розпеченим залізом випалимо все "ненормальні" символи. $ Search = preg_replace ( "/ [^ \ w \ x7F- \ xFF \ s] /", "", $ search); За ідеєю, не можна давати користувачеві можливості шукати по занадто коротким словами - крім усього іншого, це сильно завантажує сервер. Отже, дозволимо шукати тільки зі слів, які довше двох букв (якщо обмеження більше, треба замінити "{1,2}" на "{1, к-ть символів}"). $ Good = trim (preg_replace ( "/ \ s (\ S {1,2}) \ s /", "", ereg_replace ( "+", "", "$ search"))); А після заміни поганих слів - треба стиснути подвійні пробіли (вони були зроблені спеціально для коректного пошуку коротких слів). $ Good = ereg_eplace ( "+", "", $ good); Логіка Припустимо, ми хочемо надати користувачеві можливість вибирати логіку пошуку - шукати все слова або тільки одне з декількох. Якщо ви хочете зробити як в [27] Яндексі - два амперсанта означають "І" (слово1 && слово2 && слово3) або якось ще, то я не порадник. Шаманство з рядками на невеликому сайті imho не виправдовує витраченого часу. Тому форму для пошуку малюємо так: <form name = "some"> <input type = text name = "stroka"> <select name = "logic"> <option value = "OR"> шукати будь-яке з слів <option value = "AND"> шукати всі слова </ select> </ form> А в пошуковому скрипті зайвий раз перевіряємо, що користувач ввів: if (($ logic! = "AND") && ($ logic! = "OR")) $ logic = "OR"; Як буде використовуватися логіка - нижче. Статистика пошуку Непогано буде відразу інформувати користувача, скільки він знайшов рядків таблиці. Для цього робиться додатковий запит до бази: $ query = "SELECT id FROM table WHERE field LIKE '%". str_replace ( "", "% 'OR field LIKE'%", $ good). "% '"; Для статистики по окремим словами можна зробити наступне: $ word = explode ( "", $ search); while (list ($ k, $ v) = each ($ word)) {if (strlen ($ v)> 2) $ stat [] = "$ v:". mysql_num_rows (mysql_query ( "SELECT id FROM table WHERE field LIKE '% $ v%'")); else $ stat [] = "$ v: <font color = # cc0000> короткий </ font>"; }; $ Word_stats = "Статистика слів:". implode ( "", $ stat). "<br>"; unset ($ stat); Посторінковий вивід результатів Ну, коли у нас є макет для пошуку і кількість рядків результату пошуку, зробити посторінковий пошук - справа нехитра. Перевіряємо змінну $ page (незгірш від 0, не більше $ results_amount / $ rows_in_page) .В запит, який підраховує кількість рядків (дивись вище), пишемо потрібні нам поля та поля для сортування. А потім дописуємо if ($ page == 0) $ request. = "LIMIT $ rows_in_page"; else $ request. = "LIMIT". $ Page * $ rows_in_page. ",". $ Rows_in_page; (Синтаксис: LIMIT <кількість рядків> або LIMIT <кількість рядків відступу "," кількість рядків>) В результаті виконання подібного запиту ми отримаємо саме ті самі рядки, які треба виводити на страніце.Для навігації можна або малювати посилання на наступну і попередню сторінки, або, що складніше, робити панель навігації на кілька сторінок. if ($ page> 0) print ( "<a href=search.php?search=". rawurlencode($good). "&page=". ($page-1). "> попередня сторінка </a>") ; if ($ page <$ results_amount / $ rows_in_page) print ( "<a href = search.php? search =". rawurlencode ($ good). "& page =". ($ page + 1). "> наступна сторінка </ a> "); Підсвічування Щоб підсвічувати світлом або жирним шрифтом шукані слова в тексті, треба зробити всього лише наступне: $ highlight = str_replace ( "", "|", $ good); Прогалини (а вони у нас між словами стоять поодинці, і ніде подвійний пробіл не зустрічається, до того ж з кінців рядка ми їх теж вирізали) досить замінити на вертикальну риску - роздільник варіантів в регулярних виразах. "Погані" слова ми не підсвічується, тому що в основі їх не шукаємо :). У коді, який виводить текст пишемо: $ row [ "text"] = ereg_replace ($ highlight, "<font color = # cc0000> \\ 0 </ font>", $ row [ "text"]); Після написання випуску я кинувся, було, писати і собі "підсвічування". Не тут то було! У мене в тексті зустрічаються теги HTML, тому довелося багато подумати ... Вийшла ось така річ (рядок зі словами для підсвічування є): $ text = eregi_replace ( "> ([^ <] *) ($ words)", "> \\ 1 <font color = # cc0000> \\ 2 </ font> ", $ text); Доводиться дивитися, немає в тезі це слово. Однак тут постає проблема ресурсоємності такої заміни (мій K6-266 над текстом в 5 кілобайт думав цілих сім секунд). Сумно. Підсумок Застосовуючи такі прийоми, можна, по-перше, обмежити свободу дій користувача і не дати йому а) дізнатися програмну структуру сайту б) викликати перевантаження сервера (наприклад, відправивши мегабайт тексту, що складається зі слів довжиною в три букви (фраза вийшла двозначна, але переписувати Не буду :), щоб скрипт 250 тисяч разів лазив в базу) в) побачити повідомлення про помилку в результаті попадання в рядок спецсимволов мови запитів. По-друге, деякий зручність для користувача - посторінковий вивід і підсвічування. Пам'ятається в статті "Безпечний і зручний пошук" була така фраза: Частина 2. Коротко про релевантності Олег Юсов Для виведення результатів пошуку за релевантністю необхідно: * Необхідні поля VARCHAR, або будь-які з різновидів полів TEXT (SMALLTEXT, MEDIUMTEXT і т.п.) зробити ключами FULLTEXT: ALTER TABLE table ADD FULLTEXT (field) * Далі - ще простіше: $ query = "SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table ORDER BY relev DESC" Далі можна навішувати всякі LIMIT ' и та інше для зручного виведення. Нотатки: * За замовчуванням встановлено пошук слів, що містять не менше 4 символів. Правиться установкою #define MIN_WORD_LEN 4 в исходнике ft_static.c, хоча на мій погляд правити це не потрібно. * Недоступні символи% в пошуковій фразі, слова в пошуковій фразі Парс з використанням списку разделетелей. * Список роздільників слів правиться в исходнике ft_static.c. * Необхідно мінімум десяток записів в таблиці для початку обчислення релевантності. * Не можна поле relev використовувати в Клаузе WHERE: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE relev> 0 ORDER BY relev DESC хоча можна: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE MATCH field AGAINST ( '$ searchwords')> 0 ORDER BY relev DESC * Швидкість досить висока - навіть в деяких випадках швидше like пошуку * Все вищесказане працює починаючи з версії MySQL 3.23.23 При створенні індексів FULLTEXT по декількох полях можливі 2 варіанти: CREATE TABLE table (field1 VARCHAR (255), field2 TEXT, FULLTEXT (field1, field2)) CREATE TABLE table (field1 VARCHAR (255), field2 TEXT, FULLTEXT (field1), FULLTEXT (field2)) В першому випадку можливий запит: SELECT *, MATCH field1, field2 AGAINST ( '$ searchwords') as relev FROM table ORDER BY relev DESC релевантність обчислюється у всіх полів відразу. У другому випадку такий запит видасть помилку. Тут обчислюємо релевантність наступним чином: SELECT *, MATCH field1 AGAINST ( '$ searchwords') + MATCH field2 AGAINST ( '$ searchwords') as relev FROM table ORDER BY relev DESC Другий варіант трохи складніше в запитах, однак, на мій погляд краще, тому збільшується гнучкість пошуку - до кожного з полів можна задати, наприклад, коефіцієнт значущості і при підсумовуванні релевантні полів множити їх на цей коефіцієнт. Пошукова фраза буде "більше" шукатися в полях з великим коефіцієнтом. Наприклад, якщо ми робимо пошук по проіндексованих сторінок каталогу ресурсів, то поле імені сторінки зазвичай задають з великим коефіцієнтом, ніж поля мета-тегів описів або ключових слів. Частина 3: Вправи c релевантностью Спочатку як додати FULLTEXT-індекс: mysql> alter table articlea add fulltext (ztext); ERROR 1073: BLOB column 'ztext' can not be used in key specification with the used table type mysql> alter table articlea type = myisam; Query OK, 36 rows affected (0.60 sec) Records: 36 Duplicates: 0 Warnings: 0 mysql> alter table articlea add fulltext (ztext); Query OK, 36 rows affected (10.00 sec) Records: 36 Duplicates: 0 Warnings: 0 Текстові індекси можна робити тільки в таблицях типу MyISAM. Тексти беруться з таблиці і скидаються в файл індексу, і зростає обсяг бази. З приводу запитів. Не можна поле relev використовувати в Клаузе WHERE: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE relev> 0 ORDER BY relev DESC хоча можна: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table WHERE MATCH field AGAINST ( '$ searchwords')> 0 ORDER BY relev DESC Обчислення поле, звичайно ж, не можна використовувати в WHERE за всіма правилами синтаксису, але можна використовувати в HAVING: SELECT *, MATCH field AGAINST ( '$ searchwords') as relev FROM table HAVING relev> 0 ORDER BY relev DESC Пошук через MATCH, як писав Олег, робиться тільки по слову цілком. ... Втім, за релевантністю можна тільки сортувати, а вибирати по LIKE (це, звичайно, позначиться на продуктивності, навіть не знаю, наскільки). Прибираємо умова "relev> 0", залишаємо сортування. Усе інше, як і раніше - рубаємо отриманий рядок і перетворюємо в запит з декількома операторами LIKE: SELECT *, MATCH field AGAINST ( '$ searchwords') AS relev FROM table WHERE field LIKE '% $ word1%' OR field LIKE '% $ word2% 'ORDER BY relev DESC, datefield DESC Частина 4: Продолеженіе розпочатого Продовжую розпочату у вересні тему пошуку з сортуванням за релевантністю в базі MySQL. MySQL пропонує в останніх версіях бази даних використовувати для повнотекстового пошуку індексацію FULLTEXT і конструкцію MATCH field AGAINST. Однак не на всіх серверах стоїть остання версія MySQL, і не всі хостинг-провайдери хочуть оновлювати софт з міркувань надійності системи. Свого часу я припускав, що пошук з сортуванням за релевантністю треба буде робити в кілька запитів, і, отже, краще зовсім не братися за це. Думки, що релевантність можна підраховувати в самому запиті віддалено мене відвідували, але я боявся навіть уявити таку конструкцію. Однак же, працівник однієї з сайтобудівна фірм Н-ска похвалився мені системою пошуку, яку вони застосовують на своїх сайтах. Я точно не запам'ятав запит, спробую так відтворити його: SELECT title, date_format (material_date, '% e.% C.% Y') AS date1, IF (text like '% word1 word2 word3%', 3 * 10, 0) + IF (text LIKE '% word1%', 9, 0) + IF (text LIKE '% word2%', 9, 0) + IF (text LIKE '% word3%', 9, 0) AS relevance FROM table WHERE text LIKE '% word1%' OR text LIKE '% word2%' OR text LIKE '% word3%' ORDER BY relevance DESC, material_date DESC Жахливо виглядає, але працює навіть на старих версіях MySQL. Спробував порівняти швидкість роботи з ось таким запитом: SELECT title, date_format (material_date, '% e.% C.% Y') AS date1, MATCH text AGAINST ( 'word1 word2 word3') AS relevance FROM table WHERE text LIKE '% word1 % 'OR text LIKE'% word2% 'OR text LIKE'% word3% 'ORDER BY relevance DESC, material_date DESC в середньому швидкість універсального запиту в два рази менше, ніж використовує нові конструкції. Що цілком логічно - чим більше універсальність, тим більше ресурсомісткість. Спробуємо побудувати такий запит автоматично. Відрізаємо довгий рядок, а так само всі неправильні символи і короткі слова. Малюємо запит. $ Query = "SELECT title, date_format (material_date, '% e.% C.% Y') AS date1, IF (text like '%". $ Good_words. "%',". (Substr_count ($ good_words, "" ) + 1). "* 10, 0) + IF (text LIKE '%". str_replace ( "", "%', 9, 0) + IF (text LIKE '%", $ good_words). "%', 9, 0) AS relevance FROM table WHERE text LIKE '% ". str_replace ( "", "% 'OR text LIKE'%", $ good_words). "% 'ORDER BY relevance DESC, material_date DESC"; Не дуже-то складно. Для надійності і захисту від флуду можна обмежити кількість слів у запиті. Деякі доповнення до колишніх публікацій Загальна кількість знайдених рядків в таблиці. Для виведення результатів пошуку, зрозуміло, треба користуватися оператором LIMIT (щоб не писати кожен раз формування цього параметра, користуйтеся готовими функціями). Якщо ніяких операцій угруповання в запиті не робиться, краще підрахувати кількість рядків відразу в запиті - COUNT (*), а не через функцію php mysql_num_rows (). Можете перевірити на великих таблицях. Якщо виробляються групові операції, робимо запит з COUNT (DISTINCT ()), але без GROUP BY. Підсвічування. Якщо в текстах не буває html-тегів, жити простіше $ text = preg_replace ( "/ word1 | word2 | word3 / i", "<b> \\ 0 </ b>", $ text); Якщо в тексті теги використовуються, то є три варіанти а) не робити підсвічування б) оскільки теги користувач не бачить (хіба що дуже цікавий користувач), то можна зробити поле індексу, в якому не буде тегів а символи [^ \ w \ x7F- \ xFF \ s] будуть замінені на прогалини (саме ці символи вирізаються з пошукового рядка на самому початку, так що пошук по них не проводиться). Пошук і підсвічування в такому випадку зробити саме за індексом. в) робити підсвічування тексту зі звичайного поля, попередньо вирізавши теги функцією srip_tags (). Повна версія пошукового коду, як завжди, в списку файлів. Пошук з розбивкою на сторінки (Дмитро Бородін) http://php.spb.ru/mysql/limit.html


  • 1.3 , Ігор (??), 4:02, 19/01/2008 [ відповісти ] [ +++ ] [ · · · ]
+ / - Повнотекстовий пошук в MySQL на PHP (mys, LineDir, 00:10:53, 02/12/2007 [відповісти] (2)
на рахунок подсветкі..хотел б подивитися як вона у тебе працює ... маячня

Не знаю чому це маячня, у мене все працює нормально.

  • 1.6 , Юрій (??), 19:53, 11/03/2008 [ відповісти ] [ +++ ] [ · · · ]
+ / - Под'ебка це, а не повнотекстовий пошук. Навіть Гугл робить це краще - а він зовсім не шедевр. Парсер пошукових рядків повинен бути повноцінним, а до речі - що робити, якщо треба індексувати НЕ гіпертекстові або плоскі файли? Як щодо фільтрації? Песта?
  • 1.7 , KRoT (?), 00:04, 01/05/2008 [ відповісти ] [ +++ ] [ · · · ]
+ / - Ось напрацювання оптимальної системи пошуку, думаю, стаття незабаром буде дописана, але додумати і так можна ...
http://www.xbrain.ru/content/view/41/10/
> Под'ебка це, а не повнотекстовий пошук

Скрипти Дмитра Лебедєва ніколи не були "под'ебка"! А якщо у когось не вистачає розуму (до / пере) робити скрипт - ДО-СВИ-ДА-НИ-Я!

  • 1.11 , Стас (??), 13:29 20/05/2010 [ відповісти ] [ +++ ] [ · · · ]
+ / - Та це взагалі повна маячня. Для повнотекстового пошуку давно є спеціалізовані речі - наприклад Sphinx
  • 1.18 , Павло (??), 11:32, 10/12/2011 [ відповісти ] [ +++ ] [ · · · ]
+ / - Дякую автору! Гарна стаття .. дізнався для себе трохи новенького і корисного :)
Не можу зрозуміти одного чому у Вас проблема з слів оточених тегами. Для цього є strip_tags

На виході все чисто і красиво :)



Додати коментар

Спонсори:

Хостинг:



Php?
Php?
Парсер пошукових рядків повинен бути повноцінним, а до речі - що робити, якщо треба індексувати НЕ гіпертекстові або плоскі файли?
Як щодо фільтрації?
Песта?
Php?
Php?
Парсер пошукових рядків повинен бути повноцінним, а до речі - що робити, якщо треба індексувати НЕ гіпертекстові або плоскі файли?
Як щодо фільтрації?
Песта?


Новости
  • Виртуальный хостинг

    Виртуальный хостинг. Возможности сервера распределяются в равной мере между всеми... 
    Читать полностью

  • Редизайн сайта

    Редизайн сайта – это полное либо частичное обновление дизайна существующего сайта.... 
    Читать полностью

  • Консалтинг, услуги контент-менеджера

    Сопровождение любых интернет ресурсов;- Знание HTML и CSS- Поиск и обновление контента;-... 
    Читать полностью

  • Трафик из соцсетей

    Сравнительно дешевый способ по сравнению с поисковым и контекстным видами раскрутки... 
    Читать полностью

  • Поисковая оптимизация

    Поисковая оптимизация (англ. search engine optimization, SEO) — поднятие позиций сайта в результатах... 
    Читать полностью