Migration again...

13 отговора 288 прегледа
#1

Migration again...

Hi all! Хващам се, че съм добил лошия навик да поствам тук само като имам проблем, но иначе следя мързеливо какво се случва...
Преточих една база от MSSQL на MySQL, обаче имам колебания за реализацията на CONTAINS със средствата на MySQL и ми се струва, че ми убягва някой важен детайл.
От приложението се пуска заявка за търсене в едно или няколко текстови полета в базата, низът за търсене представлява поредица от ключови думи в произволен ред.
LIKE не върши работа, щото "иван%пена%гошо" не се открива в "гошо обича иван и пена" заради поредността; Комбинирането на няколко LIKE с AND или OR (според случая) с по една дума във всеки ми се вижда тромавичко. А с FULLTEXT пък не мога да укажа да се търси само в едно от полетата, включени в индекса. BTW, още търкалям MySQL 3.23.49. Ако в следващите рилийзи има някакво развитие, може да сменя.

Редактирано от bass на

Отговор
в отговор на bass #2

Re: Migration again...

Можеш да опиташ с regular expressions. [линк].

If you don't care where you are going any road will get you there
Отговор
в отговор на antipop #3

Re: Migration again...

В този подход първоначално ме обнадежди конструкцията REGEXP "(Str1|Str2)", но не открих на първо четене начин да свържа двата стринга с логическо AND вместо OR, освен това пише, че REGEXP е CaseSensitive (което не ме устройва), а и не съм пробвал дали могат да се сложат повече от два стринга (REGEXP "(S1|S2|S3...Sm|Sn)" )
Па немое да няма начин! Установил съм за себе си, че като се забатача безнадеждно с нещо, решението се оказва обидно елементарно, ама някой трябва да гледа...

Отговор
в отговор на bass #4

Re: Migration again...

нц... мисля, че маските в Перл стил от тамошните редовни изрази ще ти свършат по-добра работа.... preg_mach() там, бла бла... Не съм сигурен какво точно искаш да правиш, но прочети за тях, общо взето могат всичко.


It`s more fun to compute

The#Project - нов брой с нов дизайн
Отговор
в отговор на bass #5

Re: Migration again...

Май ти трябва FULLTEXT с BOOLEAN MODE т.е. 4.0

> А с FULLTEXT пък не мога да укажа да се търси само в едно от полетата, включени в индекса. BTW,

Амчи направи си повече от един FULLTEXT индекс - какъв е проблема?

А тоя гошо дето обичал хем иван хем пена аз не бих го търсил ама ти си знаеш ...

salle.online.bg/sig
Отговор
в отговор на salle #6

Re: Migration again...

Ееее, най-накрая се отпуши тоя дир, та да постна...
За повечкото фултекст индекси ме притеснява нещо от ръководството: "Създаването на фултекст индекс с ALTER TABLE може да се окаже доста по-бързо от вмъкването на единични записи в индексирана таблица". Тва ми мирише на голяма туткавост при ъпдейт на фултекст-индекс, камо ли на няколко такива. Гледам, че в TODO-то обещават да ги позабързат, aма все нямам време да ъпдейтна към нова версия :-((
Затрупан съм с работа като... ъъъ.. графичен дизайнер с календри преди коледа :-\\\

p.s. (Ива, Пена, etc.) Еййй, тва пусто подсъзнание, еййййй... ми те са двама братя и сестра бе - нека се обичат :-))

Редактирано от bass на

Отговор
в отговор на voyager #7

Re: Migration again...

"Не съм сигурен какво точно искаш да правиш"
Мога да опростя задачата: Търсене на няколко ключови думи в текстово поле:
1. без значение на подреждането им
2. Да не е case sensitive
3. Да се търсят ВСИЧКИ ключови думи (не поне една от тях)
Тва е принципно баси тривиалната задача, ама както казах, нещо ми убягва (я в хелпа na MySQL, я в разсъжденията...)

А иначе базата не е достъпна през уеб, ползвам я локално през C API и libMySQL, та не схванах съвсем как да ползвам нещо от PERL в MySQL-специфичните SQL-конструкции.

Отговор
в отговор на bass #8

Re: Migration again...

char keywords[][]; //dvumeren masiv s dumite /*vseki podmasiv e duma

char* query="SELECT * FROM table WHERE"; //zaqvkata
int j=0;
while(someFunction()) { //tuka ne moga v momenta da mislq kak stavashe obhojdane //na dvumeren masiv v C, ama shte go izmislish

//dobavqne kym stringa - и тва съм го забравил в момента, ама ти знаеш
//нещо като query+="LIKE '% "+keiwords[j]+" % AND";
i++;
}

И после използваш query. Извинявам се, че толкова грубо съм го направил, но мисля, че е достатъчно да разбереш идеята. Логиката ще ти е малко по-сложна от това де, но основата е такава. Надявам се думите ти са разделени с интервал, иначе ще трябва да се добавят някакви неща.
А иначе си прав, че перл няма да свърши работа - не се сетих, че не влизаш там през веба

The#Project - нов брой с нов дизайн
Отговор
в отговор на bass #9

Re: Migration again...

Тва ми мирише на голяма туткавост при ъпдейт на фултекст-индекс, камо ли на няколко такива.

То това е така за всички индекси - колкото повече - толкова по-бавни промени.

От друга страна пък всички останали варианти на търсене на подстринг няма да използват хич никакъв индекс тъй, че .... търси му златната среда нейде

salle.online.bg/sig
Отговор
в отговор на bass #10

Re: Migration again...

Глей сега да ти дам една идея, бъпреки че сигурно няма да ти свърши работа щото изобщо не знам как ша работи с кирилица и български. Накратко правиш си твой механизъм за търсене:

да речем че таблицата в която искаш да търсиш е

create table s (code int, descr varchar (200))
и code ти е примару кл. и искаш да търсиш в descr.

правиш си отделна таблица
create table metaindex (word char (30), sound_code char (4), code(int))
create index sind on metaindex (word)

Тая втора таблица (метаиндекс) си я зареждаш с една stored proc, която чете таблицата s, и за всеки ред изважда всичките думи от descr и ги зарежда в метаиндекс заедно със съответния code. Същевременно процедурата смята soundex() а всяка дума и го зарежда в съответното поле -- е това не знам ка ще работи с български думи.

За бъдещи инсерти, същия код можеш да го плеснеш в един тригер в/у s.

Та като я свършиш тая подготвителна работа, търсенето на думи се свежда до join na s i metaindex със съответните OR или UNION за повече от една дума.

Ако търсенето на думите не върне резултат, можеш да пуснеш второ търсене по soundex.

Ako ти звучи интесно, кажи ще ти постна съответния код. (sybase 11.9.2, трябва да върви и на ms sql server)

Редактирано от бaй Любo на

Отговор
в отговор на voyager #11

Re: Migration again...

Тва хубаво, ама, както казах в пърия пост, не ми се вижда много грамотно да AND-вам LIKE-ове (primerno okolo 10-20) и после тия 10-20 LIKE да ги копирам за всяко поле, в което юзърът е решил да души :-\\
Иначе парсването на потребителския вход към думи не ми е проблем, отработил съм го. А и ако ползвам FULLTEXT индекс не се и налага...

Редактирано от bass на

Отговор
в отговор на бaй Любo #12

Re: Migration again...

Ааааа, аз откак salle ме нави да прая допълнителни таблици за locks и copy мноо съм задобрял с тая техника, ама този път викам твърдо НЕ! За таквоз нещо - нивгас :-))) За една конверсия такива гимнастики няма да правя, неее :-))
А иначе, ако се абстрахираме от прозаичната практика, нищо чудно подобен механизъм да се ползва вътрешно в някоя от познатите СУБД...

Отговор
в отговор на salle #13

Re: Migration again...

Май така ще стане. Ще му пусна 2 фултекст-индекса (мога да групирам полетата така) и ще се надявам, че докато таблицата стане 100000 записа, ще излезе супер-едишън на MySQL :-)).
А не е изключено да намеря и време за ъпгрейд :-\\

Отговор
в отговор на bass #14

Re: Migration again...

да бе, аз само казвам...

Отговор