Задавайте вопросы, мы ответим
Вы не зашли.
Кто знает про регулярные выражения, помогите пожалуйста.
Делаю поиск по сайту. Нужно составить регулярное выражение для поиска слова , например "Москва". Если в тексте встречается выражение типа "г.Москва, где я живу", то единственный способ найти это слово, это запрос вида:
like '%word%', где word - любое слово, в т.числе Москва.
Но запрос не подходит, так как если в поиске будет короткое слово, запрос будет очень много ненужных вариантов выдавать. Ищу, допустим, слово "кот", а MYSQL мне и слово "который" выдаст и другие ненужные слова. Как с помощью регулярных выражений задать символы точек, запятых, двоеточий и тире, чтобы составить более корректный запрос?
Неактивен
запросы с регулярными выражениями в общем случае не используют индексы (так же как и LIKE %word%) и использовать их для вашей цели думаю не стоит...
Посмотрите в сторону полнотекстового поиска (kw: fulltext)
Неактивен
По поводу индекса согласен с Shopen, однако, на первый вопрос тоже отвечу -
Вы можете использовать регулярные выражения, если будете писать не LIKE, а
RLIKE, например, RLIKE '[[:<:]]кот[[:>:]]'.
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
Неактивен
Спасибо за ссылку, почитаю.
Правда не понял, при чём здесь индексы?
Неактивен
Если у Вас таблица в 10 строк, то никакой проблемы с тем, чтобы сравнить все строки с регулярным
выражением, не возникает. Если же у Вас таблица вырастет со временем до 10 миллионов строк, то
для того, чтобы найти строки, удовлетворяющие определенному критерию, потребуется в
несколько миллионов раз больше времени (т.к. данные будут браться не из кэша, как происходит
в случае маленькой таблицы, а с диска). Для того, чтобы ускорить этот процесс и используются
индексы.
Неактивен
Очень полезная статья. Правда, после того, как её перевёл на русский, надо понять что к чему в ней, что за команды или не команды там такие. Очень хорошее рег. выражение. По сути оно очень упрощает поиск.
Только вот у меня возникла проблема.Когда я ищу RLIKE '[[:<:]]кот[[:>:]]', то база выдаёт мне слова только с маленькой буквы (хотя есть строки со значением "Кот" с большой буквы. Когда я задаю такое рег. выражение
RLIKE '[[:<:]]Кот[[:>:]]'
то он всё ищет нормально, как с маленькой так и с большой буквы. У меня с кодировкой проблемы или это особенность регулярного выражения? Использовал для тестирования phpmyadmin. Вроде collation настроил. Использовал utf8_unicode_ci. В запросе также пробовал конструкцию collation, но это ничего не изменило.
Отредактированно sito-corito (22.07.2008 19:15:09)
Неактивен
Да, похоже, это бага. В cp1251 отрабатывает правильно с учетом кодировки, в UTF8
рассматривает как бинарную
P.S. У меня с большой буквы не ищет маленькие в том числе.
Неактивен
Хотелось бы уточнить, что подобная конструкция регулярного выражения, наверное, единственный нормальный способ поиска слова в базе. А всякие там like '%слово_%' c символами подчёркивания (для "изображения" любого символа, в том числе запятых и точек) только усложняют задачу.
Неактивен
Нет, правильный способ всё-таки, полнотекстовый поиск. По указанным уже выше причинам.
http://dev.mysql.com/doc/refman/5.1/en/ … earch.html
Неактивен
sito-corito написал:
Хотелось бы уточнить, что подобная конструкция регулярного выражения, наверное, единственный нормальный способ поиска слова в базе.
не изобретайте велосипед. Вашу задачу давно решили - красиво, удобно и быстро.
Регулярные выражения в SQL - это очень редко встречаемая задача - некрасивая (посмотрите на ваш пример), не удобная (потому что не PCRE а POSIX) и ОЧЕНЬ медленная на большинстве задач. Медленнее только левый LIKE %...%. и то не всегда.
На моей практике использовать REGEXP (==RLIKE) понадобилось один раз - когда в базе была таблица, в которой был столбец с регулярными выражениями и через него шло объединение, типа такого (по памяти):
SELECT tWords.word FROM tWords JOIN tRegexp ON tWords.word REGEXP CONCAT(tRegexp.rule, '$') WHERE ...
тут просто некуда было деться, но работало быстро, так как в tWords.word лежали слова, да и регулярки были наипростейшими, по сути набор символьных классов. Если бы там был текст - мне страшно представить, сколько бы на эти запросы уходило времени (~миллион слов, ~500 регулярок).
Если ваш поиск будет производиться по табличке в которой с десяток строк, то это еще куда ни шло. Но тормозную мину вы все равно заложите. И главное зачем?
Если по какой то причине полнотекстовый поиск не устраивает - есть и другие решения, например можно создать доп. таблицу со словами + ссылки на источник слова - и по ней искать.
Отредактированно Shopen (24.07.2008 13:00:45)
Неактивен
Не могу согласится с тем, что полнотекстовый поиск идеально подходит для задачи поиска. По крайней мере для меня. Прочитал кое-что про такой поиск. Данные в моей таблице могут быть как очень короткими, так и длинными. Полнотекстовый поиск имеет ограничения на длину искомых слов, сам определяет релевантность и иногда не выдаёт результат, даже если слово есть в базе. И как изменить параметры такого поиска на сервере я даже представить не могу. А я бы хотел более прогнозируемый результат.
Индексировать поле, в котором я произвожу поиск, наверное смысла нет. У меня там будут не фамилии и имена, а какой-то текст.
Не имею практического опыта и хотелось бы приблизительно оценить, сколько уходит времени для поиска с помощью регулярных выражений в таблице с приблизительно миллион или более строк с текстом в два-три предложения (без индексов, а имено поиск в каждой строке). Если у кого-то есть такие данные? Сколько секунд запрос обрабатывается? Был бы признателен за информацию А то я собираюсь делать поиск с использованием регулярного выражения, в котором есть подзапрос where с ещё одним регулярным выражением.
Отредактированно sito-corito (26.07.2008 01:14:36)
Неактивен
Некоторые параметры FULLTEXT можно настраивать, в частности минимальную длину слова http://dev.mysql.com/doc/refman/5.1/en/ … uning.html
Посмотрите также BOOLEAN MODE http://dev.mysql.com/doc/refman/5.1/en/ … olean.html
Как более мощная альтернатива, поддерживающая русский язык, Вам может подойти Sphinx.
Самый простой способ узнать время выполнения запроса - создать тестовую таблицу, внести в нее миллион записей и выполнить запрос.
Неактивен
sito-corito написал:
Не могу согласится с тем, что полнотекстовый поиск идеально подходит для задачи поиска. По крайней мере для меня.
расскажите чем конкретно не подходит?
sito-corito написал:
Полнотекстовый поиск имеет ограничения на длину искомых слов, сам определяет релевантность и иногда не выдаёт результат, даже если слово есть в базе. И как изменить параметры такого поиска на сервере я даже представить не могу. А я бы хотел более прогнозируемый результат.
Про изменение длины слова вам уже сказали. Насчет релевантности - а вы как - сами ее собрались считать с помощью регулярных выражений?
sito-corito написал:
Индексировать поле, в котором я произвожу поиск, наверное смысла нет. У меня там будут не фамилии и имена, а какой-то текст.
А какая разница что в поле фамилии или слова? Если поле по которому ищете не будет проиндексировано - то тормоза будут по любому (при ваших ожидаемых объемах особенно).
Индексировать можно либо воспользовавшись fulltext, либо сделав свою таблицу индекс (наиболее гибкий путь, но и наиболее затратный) либо воспользовавшись каким то существующим движком, типа сфинкса (он тоже создаст разумеется индекс где то для себя), который вам посоветовал rgbeast
sito-corito написал:
Не имею практического опыта и хотелось бы приблизительно оценить, сколько уходит времени для поиска с помощью регулярных выражений в таблице с приблизительно миллион или более строк с текстом в два-три предложения (без индексов, а имено поиск в каждой строке). Если у кого-то есть такие данные? Сколько секунд запрос обрабатывается? Был бы признателен за информацию А то я собираюсь делать поиск с использованием регулярного выражения, в котором есть подзапрос where с ещё одним регулярным выражением.
оценить время невозможно - это зависит от конкретной железки, от настроек mysql от конкретных данных в базе.
можно примерно эмпирически сказать, что разница между поиском по регулярным выражениям и полнотесктовым (или тем же сфинксом) в лучшем случае будет примерно один-два порядка. в худшем, если на хостинге есть ограничения рукотворного характера или аппаратного - то вы просто не дождетесь результата.
если вам очень нужна гибкость - сделайте свой поиск, но только не на регулярных выражениях. Примерный алгоритм такой:
- Текстовые поля разбиваете на слова, может быть выкидываете короткие (предлоги,союзы...)
- Полученные слова пропускаете через морфологический анализ (если нужна морфология)
- Полученные нормальные формы слов или слова - заносите в таблицу (tWordIndex) попутно сохраняя в еще одну таблицу (tWordRelations) id слова + id записи откуда слово + количество раз, которое оно в этой записи встречалось (или словоформа) + еще какие то данные, которые вам нужны, например вы можете тут высчитывать вес слова в записи, на основе своих собственных параметров (*3 если внутри <h1>слово</h1>, например)
- Делаете нужные индесы в таблицах
При поиске ищете так (это схематичный запрос):
SELECT tSource.text JOIN tWordIndex JOIN tWordRelations WHERE tWordIndex IN 'слова_из_формы_поиска,разбитые_по_разделителям' ORDER BY 'поле_с_весами_слов'
перед этим приводите поисковый запрос к нормальной морфологической форме (если требуется)
Это только примерная схема, тут есть что и додумать и дооптимизировать
Неактивен
- Текстовые поля разбиваете на слова, может быть выкидываете короткие (предлоги,союзы...)
- Полученные слова пропускаете через морфологический анализ (если нужна морфология)
- Полученные нормальные формы слов или слова - заносите в таблицу (tWordIndex) попутно сохраняя в еще одну таблицу (tWordRelations) id слова + id записи откуда слово + количество раз, которое оно в этой записи встречалось (или словоформа) + еще какие то данные, которые вам нужны, например вы можете тут высчитывать вес слова в записи, на основе своих собственных параметров (*3 если внутри <h1>слово</h1>, например)
- Делаете нужные индесы в таблицах
Вот примерно такой поиск я и делаю.
Яндекс и Гугл и другие поисковики обзавидуются, наверное.
Неактивен
sito-corito написал:
Вот примерно такой поиск я и делаю.
тогда непонятно - а зачем вам понадобились регулярные выражения?
sito-corito написал:
Яндекс и Гугл и другие поисковики обзавидуются, наверное.
Сомневаюсь
Неактивен