php mysql поиск по словам

Поиск по тексту в MySQL

Недавно начались некоторые опыты с морфологией, чтобы их произвести и обкатать некоторые алгоритмы, пришлось воспользоваться словарем от OpenCorpora. В исходном виде табличка со словарем включает около 405 тысяч строк, в каждой из них информация по формам слова, его лемме, род, время, падеж, одушевленное или нет, всё это занимает около 489 мегабайт.

Мне понадобилось вытаскивать по конкретному слову его данные, для этого составил табличку такого типа

idlemma_idwordgramgram_descr
11клавиатура..

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

Можно прибегнуть к системам полнотекстового поиска, может так и сделаю, но меня первым делом смущает работа по http некоторых таких систем, если надо будет 1000 запросов в секунду кидать, ну я их еще проверю, еще планирую потестировать всякие MongoDB.

Итак, поехали, попробуем получить клавиатура. Как видим, 2.4 сек, иногда до 3.4 доходило, это очень ужасно.

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

Теперь попробуем по точному совпадению key=>val. Ситуация особо не меняется, странно, но даже дольше выполняется, несколько раз перезапускал и оно только вот так, 2.5 сек, такой результат еще более ужасный.

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

Теперь попробуем такую мощную штуку, как полнотекстовый поиск, для этого нужно добавить полнотекстовый индекс к полю word.

К слову, у меня этот индекс был уже изначально на момент тестирования, выполняем запрос

И о чудо, 0.0004 сек, вот такой результат более чем приличный

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

Тут видно, что предлог «за» есть в таблице..

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

Но так не сможет его найти, т.к. есть ограничение

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

Давайте попробуем снять это ограничение, пропишем в конфиг [mysqld]

Ничего не выходит, наверно нельзя по одной или двум буквам искать, значит нам это не совсем подходит. Но мы можем например выделить все слова до 3х символов в отдельную таблицу и там будет искать их быстро обычными методами.

В любом случае, этот метод будет достаточно хорош для поиска по текстам на сайте, например по описаниям товаров, если особенно на обычном хостинге, где нет Sphinx, ElasticSearch и другого такого.

Определим сколько у нас максимальное по длине слово

Получим 35, слова такие конечно редкие, но мы должны предусмотреть максимальную базу данных

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

Попробуем тип поля сделать не text, а varchar 50, а потом поискать стандартным способом через like, ничего не поменялось.

Попробуем сравнение изменить на utf8_bin

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

С Like ситуация не поменялась, с полным WHERE тоже, но теперь появилась возможность сделать простой индекс не полнотекстовый для поля word

После добавления индекса к полю, у меня стало искать за доли секунды

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

При таком раскладе, скорость получения данных по словам будет 2500 слов в секунду, не плохо. Правда сравнение utf8_bin накладывает некоторые ограничения, например нет регистронезависимого поиска, нужно при выборке и хранении понижать регистр, хотя тут вроде итак всё в нижнем регистре.

Попробуем поменять сравнение в поле на utf8_unicode_ci, и снова перестроить индекс может там не сильно будет потеря, да, MariaDB вполне справляется, то что пишут на форумах про ускорение в сравнении bin наверно уже устарело.

Теперь попробую еще одну идею, добавить в таблицу поле length и записать в него длину, сделаем его INT(2), ну максимум у нас все равно слово может быть 50 букв, хотя это там даже не слово, а какие то длинные названия. И сделаем поле индексированным.

Сделаем такой запрос для его заполнения

А теперь попробуем поискать вот так

Нет, это не дало результата должного, уже нет такого критичного времени, которое может оптимизироваться, но идея заключалась в том, чтобы выбрать по индексированному полю с длиной строки, а потом из этого уже по слову искать.

Выводы: если нужна выборка по текстовому полю, например ЧПУ страницы сайта, то надо использовать поле varchar фиксированного размера и добавлять к нему индекс, как видите, с миллионами записей справляется идеально. Если же нужен поиск по текстам описаний (text) с вхождением слов, то лучше использовать полнотекстовый поиск, он достаточно быстрый.

Паттерны проектирования

Недавно я начал читать книжку по паттернам проектирования, это такие общеприняттые и…

Источник

Полнотекстовый поиск MySQL

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

Здравствуйте, уважаемые читатели блога LifeExample, задача полнотекстового поиска по таблицам базы данных, является неотъемлемой, практически, для каждого веб-ресурса. Все новички рано или поздно сталкиваются с вопросом, «как реализовать полнотекстовый поиск по сайту?» конечно сначала задача всплывает несколько иначе: «как сделать поиск по сайту?».

Отличие обычного поиска от полнотекстового в том что, при первом искать сущности сайта, будь то товары магазина или статьи блога, можно по конкретному параметру, например по дате добавления. Полнотекстовый поиск, в свою очередь, подразумевает поиск по совпадающим ключевым словам запроса и текста искомого товара или статьи.

Самым наглядным примером полнотекстового поиска являются поисковые системы, такие как yandex.ru или google.ru, при вводе запроса «Полнотекстовый поиск MySQL» в поисковую строку система разобьет фразу на три слова:

Затем проанализирует имеющиеся сущности, в данном случае это набор проиндексированных страниц сайтов, на наличие совпадений с каждым словом. Те страницы, которые имеют хотя бы одно из слов всей фразы либо их словоформ, будут выведены в поисковую выдачу.

Надо заметить, что поисковые системы обладают множеством алгоритмов позволяющих найти наиболее релевантную информацию по введенной фразе, но мы сегодня создадим самый простейший полнотекстовый поиск с помощью MySQL.

Как сделать полнотекстовый поиск MySQL

Какой бы не казалась задача полнотекстового поиска сложной, решается она очень быстро и просто. Беря в расчет, что сегодня большинство сайтов используют в качестве хранилища информации базу данных MySQL, то далее речь пойдет о реализации поиска по сайту именно по таблицам MySQL.

Реализовать поиск по таблицам MySQL можно разными способами:

Первые два оператора самый примитивный вариант для поиска по сайту, и кроме того очень медлительный и требующий большой производительности сервера.

Поиск по сайту с помощью оператора LIKE

Например, реализовать поиск по таблице статей, используя оператор LIKE, можно следующим запросом:

Данный запрос выдаст все записи, т.е. все статьи в тексте которых встретится слово «новость», если в содержании самой статьи нет данного слова, но оно в присутствует в заголовке, статья не будет найдена.

Чтобы искать статьи также и по совпадению в заголовках, можно усовершенствовать запрос:

Этот SQL запрос учитывает два текстовых поля, по которым произойдет поиск статьи, но использует уже несколько операторов LIKE, а это двойная нагрузка на сервер. Кроме того если пользователь запросит статьи по фразе «новость дня», то получи те статьи, которые содержат исключительно именно такую фразу: «новость дня».

MySql match – все что нужно для поиска по сайту

В арсенале программиста, использующего mysql, имеется стандартный инструмент для полнотекстового поиска MySql – операторы: MATCH и AGAINST.

Возьмем, к примеру, задачу поиска товаров по базе интернет магазина. Как правило, товар имеет ряд текстовых характеристик, таких как: название, описание, артикул, ключевые слова и др.

Используя для реализации полнотекстового поиска MATCH и AGAINST запрос может выглядит так:

При этом, для работоспособности запроса должен существовать индекс таблицы товаров с типом FULLTEXT, объединяющий в себе перечень полей для поиска:

php mysql поиск по словам. Смотреть фото php mysql поиск по словам. Смотреть картинку php mysql поиск по словам. Картинка про php mysql поиск по словам. Фото php mysql поиск по словам

Имя индекса может быть любым, а в полях должны быть перечислены, все те, которые будут участвовать в поиске. При данном индексе, показанном на картинке, нельзя делать выборку только по одному из указанных полей.

Искать не точное соответствие по введенной фразе и соответствие по ее частям можно таким образом:

При таком запросе в результат попадут записи имеющие вхождения фрагментов слов ful и nam

Надо учесть, что при работе с MATCH запрещено использовать в качестве именно полей зарезервированные слова.

Существует список запрещенных к использованию слов, то есть следующими словами нельзя называть поля таблиц, чтобы потом использовать их в полнотекстовом поиске MySql:

a’sableaboutaboveaccording
accordinglyacrossactuallyafterafterwards
againagainstain’tallallow
allowsalmostalonealongalready
alsoalthoughalwaysamamong
amongstanandanotherany
anybodyanyhowanyoneanythinganyway
anywaysanywhereapartappearappreciate
appropriatearearen’taroundas
asideaskaskingassociatedat
availableawayawfullybebecame
becausebecomebecomesbecomingbeen
beforebeforehandbehindbeingbelieve
belowbesidebesidesbestbetter
betweenbeyondbothbriefbut
byc’monc’scamecan
can’tcannotcantcausecauses
certaincertainlychangesclearlyco
comcomecomesconcerningconsequently
considerconsideringcontaincontainingcontains
correspondingcouldcouldn’tcoursecurrently
definitelydescribeddespitediddidn’t
differentdodoesdoesn’tdoing
don’tdonedowndownwardsduring
eacheduegeighteither
elseelsewhereenoughentirelyespecially
etetceveneverevery
everybodyeveryoneeverythingeverywhereex
exactlyexampleexceptfarfew
fifthfirstfivefollowedfollowing
followsforformerformerlyforth
fourfromfurtherfurthermoreget
getsgettinggivengivesgo
goesgoinggonegotgotten
greetingshadhadn’thappenshardly
hashasn’thavehaven’thaving
hehe’shellohelphence
herherehere’shereafterhereby
hereinhereuponhersherselfhi
himhimselfhishitherhopefully
howhowbeithoweveri’di’ll
i’mi’veieifignored
immediateininasmuchincindeed
indicateindicatedindicatesinnerinsofar
insteadintoinwardisisn’t
itit’dit’llit’sits
itselfjustkeepkeepskept
knowknownknowslastlately
laterlatterlatterlyleastless
lestletlet’slikeliked
likelylittlelooklookinglooks
ltdmainlymanymaymaybe
memeanmeanwhilemerelymight
moremoreovermostmostlymuch
mustmymyselfnamenamely
ndnearnearlynecessaryneed
needsneitherneverneverthelessnew
nextninenonobodynon
nonenoonenornormallynot
nothingnovelnownowhereobviously
ofoffoftenohok
okayoldononceone
onesonlyontoorother
othersotherwiseoughtourours
ourselvesoutoutsideoveroverall
ownparticularparticularlyperperhaps
placedpleasepluspossiblepresumably
probablyprovidesquequiteqv
ratherrdrereallyreasonably
regardingregardlessregardsrelativelyrespectively
rightsaidsamesawsay
sayingsayssecondsecondlysee
seeingseemseemedseemingseems
seenselfselvessensiblesent
seriousseriouslysevenseveralshall
sheshouldshouldn’tsincesix
sosomesomebodysomehowsomeone
somethingsometimesometimessomewhatsomewhere
soonsorryspecifiedspecifyspecifying
stillsubsuchsupsure
t’staketakentelltends
ththanthankthanksthanx
thatthat’sthatsthetheir
theirsthemthemselvesthenthence
therethere’sthereaftertherebytherefore
thereintheresthereuponthesethey
they’dthey’llthey’rethey’vethink
thirdthisthoroughthoroughlythose
thoughthreethroughthroughoutthru
thustotogethertootook
towardtowardstriedtriestruly
trytryingtwicetwoun
underunfortunatelyunlessunlikelyuntil
untoupuponususe
usedusefulusesusingusually
valuevariousveryviaviz
vswantwantswaswasn’t
waywewe’dwe’llwe’re
we’vewelcomewellwentwere
weren’twhatwhat’swhateverwhen
whencewheneverwherewhere’swhereafter
whereaswherebywhereinwhereuponwherever
whetherwhichwhilewhitherwho
who’swhoeverwholewhomwhose
whywillwillingwishwith
withinwithoutwon’twonderwould
wouldn’tyesyetyouyou’d
you’llyou’reyou’veyouryours
yourselfyourselveszero

Надо сказать, я потратил не один час на то чтобы понять, почему мой полнотекстовый поиск MySql то работает, то не очень, а ведь все дело оказалось именно в совпадении наименований полей с зарезервированными словами.

Как я и обещал, в начале статьи, задача реализации полнотекстового поиска в MySQL сводится к минимуму действий:

Возникли вопросы? Пишите в комментариях! Подписывайтесь на RSS рассылку, впереди много интересных и полезных статей.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *