Вверх ↑
Этот топик читают: Гость
Ответов: 409
Рейтинг: 17
#1: 2009-05-18 20:58:30 ЛС | профиль | цитата
Есть задумка, сделать полнотекстовый, морфологический поиск по запросу в БД.
В принцепе решение я уже придумал, вот только нужно словари подходящие найти и залить их в таблицу базы данных.
Но хотелось бы спросить может кто уже сталкивался с такой задачей?
карма: 0

0
Ответов: 409
Рейтинг: 17
#2: 2009-05-21 14:09:20 ЛС | профиль | цитата
Видимо никто не делал такого
Расскажу как я решил этот вопрос, может кому пригодится.
Со словарем решил не заморачиваться, а сделал псевдо-морфологический поиск.
Логика такая - есть запрос: подошва резиновая
нужно найти в базе данных все синонимы, например: подошва из резины или обувь на резиновой подошве и т.д.
Вот схема решения:
code_13376.txt

Незнаю есть ли в SQLite полнотекстовый поиск, формулу я от MySQL написал.
Конечно при таком поиске много мусора сыпится, но зато существенно расширяется граница поиска.
карма: 0

0
файлы: 1code_13376.txt [19.7KB] [857]
Ответов: 8926
Рейтинг: 823
#3: 2009-05-21 14:55:25 ЛС | профиль | цитата
Pirr, конечно, запрос с выкинутыми окончаниями не совсем корректен, но на безрыбье и рак рыба
По подготовке слов: наверное надо привести все слова к нижнему регистру; удалять лишние пробелы желательно в цикле, чтобы не пропустить и тройные и сколько может поставить нечаянно пользователь code_13378.txt
карма: 19

1
файлы: 1code_13378.txt [1.3KB] [172]
Голосовали:Konst
Ответов: 409
Рейтинг: 17
#4: 2009-05-21 16:19:56 ЛС | профиль | цитата
Леонид писал(а):
наверное надо привести все слова к нижнему регистру; удалять лишние пробелы желательно в цикле, чтобы не пропустить и тройные и сколько может поставить нечаянно пользователь

думал над этим, но решил пока не усложнять схемы. Регистр вроде не влияет на запрос.
А в цикле я хотел бы вообще удалять из текста все знаки припинания, тире, слэши и т.д. но пока не знаю как это сделать красиво.
И еще хотелосьбы чтобы количество слов было неограниченным, и схема былабы динамической - в зависимости от количества слов, а то у меня пять раз повторяется одна и таже вложенная схема - это не красиво.
карма: 0

0
Ответов: 8926
Рейтинг: 823
#5: 2009-05-21 22:12:24 ЛС | профиль | цитата
Pirr, приблизительно так : code_13384.txt
Верхняя и нижняя границы любые.
карма: 19

0
файлы: 1code_13384.txt [5.5KB] [167]
Ответов: 409
Рейтинг: 17
#6: 2009-05-21 22:40:57 ЛС | профиль | цитата
Леонид у тебя интересный подход к схемам, у меня както по другому получается... например до такого оригинального цикла с удалением пробелов я бы не додумался.
А вторая схема вообще - супер , я немного по другому пути пошол. Стал отделять от строки по одному слову, и если еще остается строка то от нее в цикле снова отделяется слово, затем оставил одну вложеную схему обрезающую слова куда по очереди направляю слова, вот только неполучается снова складывать эти слова в строку.
В общем спасибо за схему, сейчас буду разбираться в ней.
------------ Дoбавленo в 09.32:
Вот сделал гибрид из двух схем:

Add(MainForm,2953706,21,35)
{
Width=658
Height=166
Caption="Псевдо морфология"
Position=1
}
Add(Edit,6750925,84,35)
{
Left=85
Top=50
Width=305
Text="Первый в мире космический корабль полетел на луну"
}
Add(Button,2339814,21,91)
{
Left=395
Top=50
link(onClick,3377475:doWord,[])
}
Add(Length,1083171,189,175)
{
link(Str,8192028:Var2,[])
}
Add(Hub,2748098,140,91)
{
link(onEvent1,1083171:doLength,[(176,97)(176,181)])
link(onEvent2,16583158:doCompare,[(166,104)(166,230)])
}
Add(MultiElementEx,16583158,189,224)
{
link(onEvent2,2335369:doStrCat,[(233,230)(233,264)(167,264)(167,286)])
link(Data,1083171:Result,[])
link(Data1,8192028:Var3,[(202,156)])
}
BEGIN_SDK
Add(EditMultiEx,7366698,21,21)
{
WorkCount=#9:doCompare|
EventCount=#8:onEvent2|
VarCount=#3:Var|
DataCount=#4:Data|5:Data1|
Width=601
Height=431
link(doCompare,12465132:doCompare,[(77,27)(77,167)])
link(Var,7442844:Var,[(27,428)(524,428)])
}
Add(If_else,12465132,133,161)
{
Type=3
Op2=String(3)
link(onTrue,10967219:doEvent1,[(178,167)(178,258)])
link(onFalse,7339994:doCompare,[])
link(Op1,136591:Var2,[])
}
Add(If_else,7339994,189,168)
{
Type=3
Op2=String(5)
link(onTrue,8153137:doEvent1,[(229,174)(229,160)])
link(onFalse,854481:doEvent1,[(230,181)(230,188)])
link(Op1,136591:Var3,[(195,58)])
}
Add(GetDataEx,136591,126,49)
{
link(Data,7366698:Data,[(139,37)(27,37)])
}
Add(Copy,14864205,273,161)
{
Position=1
link(onCopy,13422765:doEvent1,[])
link(Str,9600820:Var2,[])
link(Count,14190546:Result,[])
}
Add(Math,14190546,287,119)
{
OpType=1
Op2=1
link(Op1,10608593:Var2,[])
}
Add(Hub,8153137,238,154)
{
link(onEvent1,14190546:doOperation,[(270,160)(270,125)])
link(onEvent2,14864205:doCopy,[])
}
Add(EventFromData,16594654,378,161)
{
}
Add(Hub,13422765,322,161)
{
OutCount=3
link(onEvent1,16594654:doData,[])
link(onEvent2,25222:doStrCat,[(371,174)(371,251)])
link(onEvent3,3370152:doData,[(350,181)(350,384)])
}
Add(Copy,5499976,448,189)
{
Position=1
link(onCopy,14701210:doEvent1,[])
link(Str,9600820:Var3,[(454,100)])
link(Count,9912473:Result,[])
}
Add(Math,9912473,462,126)
{
OpType=1
Op2=2
link(Op1,10608593:Var3,[(468,107)])
}
Add(EventFromData,7555955,553,189)
{
}
Add(Hub,14701210,490,189)
{
OutCount=3
link(onEvent1,7555955:doData,[])
link(onEvent2,6848094:doStrCat,[(528,202)(528,314)])
link(onEvent3,7632544:doData,[(516,209)(516,293)(401,293)(401,377)])
}
Add(GetDataEx,10608593,280,98)
{
link(Data,136591:Var1,[(293,78)(117,78)(117,58)])
}
Add(Hub,854481,420,182)
{
link(onEvent1,9912473:doOperation,[(448,188)(448,132)])
link(onEvent2,5499976:doCopy,[])
}
Add(GetDataEx,9600820,266,91)
{
link(Data,6970006:Var3,[(279,88)])
}
Add(Hub,14189836,455,371)
{
InCount=3
link(onEvent1,7442844:doIndex,[])
link(onEvent2,7366698:onEvent2,[(600,384)(600,27)])
}
Add(GetIndexData,7442844,518,371)
{
Count=3
link(Data1,6970006:Var2,[(524,245)(62,245)])
link(Data2,25222:Result,[(531,305)(412,305)])
link(Data3,6848094:Result,[(538,355)(559,355)])
}
Add(Hub,10967219,217,252)
{
link(onEvent2,8322912:doData,[(240,265)(240,391)])
}
Add(DoData,8322912,308,385)
{
Data=Integer(0)
link(onEventData,14189836:doEvent3,[])
}
Add(DoData,3370152,364,378)
{
Data=Integer(1)
link(onEventData,14189836:doEvent2,[])
}
Add(DoData,7632544,413,371)
{
Data=Integer(2)
link(onEventData,14189836:doEvent1,[])
}
Add(StrCat,6848094,553,308)
{
Str2="*"
link(Str1,7555955:GetData,[])
}
Add(StrCat,25222,406,245)
{
Str2="*"
link(Str1,16594654:GetData,[(412,219)(384,219)])
}
Add(GetDataEx,6970006,49,79)
{
link(Data,7366698:Data1,[(62,52)(34,52)])
}
END_SDK
Add(Label,4441798,314,420)
{
Left=15
Top=90
Width=620
}
Add(GetDataEx,8192028,182,147)
{
link(Data,3377475:Res,[(195,137)(90,137)])
}
Add(FormatStr,11994204,258,420)
{
DataCount=1
Mask="SELECT * FROM t WHERE MATCH (k) AGAINST("%1" IN BOOLEAN MODE)"
link(onFString,4441798:doText,[])
}
Add(StrCat,2335369,189,280)
{
Str2=" "
link(onStrCat,7756213:doStrCat,[(233,286)(233,318)(168,318)(168,342)])
link(Str1,16583158:Var,[])
}
Add(GetDataEx,7103707,188,385)
{
Angle=3
link(Data,7756213:Result,[(188,394)])
}
Add(MultiElementEx,3377475,84,91)
{
@Hint=#59:Разделение строки на слова с удалением всех лишних символов|
link(onRes,2748098:doEvent1,[])
link(onEnd,6118933:doEvent1,[(124,104)(124,426)])
link(Words,6750925:Text,[])
}
BEGIN_SDK
Add(EditMultiEx,13214083,21,21)
{
WorkCount=#24:doWord=Обработать строку|
EventCount=#50:onRes=Строка сокращённых слов разделённых пробелом|25:onEnd=Вычисления окончены|
VarCount=#48:Res=Строка сокращённых слов разделённых пробелом|
DataCount=#5:Words|
Width=846
Height=179
link(doWord,5719433:doModify,[(31,27)(31,76)])
link(Res,10295050:Value,[(27,179)(783,179)])
}
Add(StrCase,5719433,42,70)
{
link(onModify,11837915:doString,[])
link(Str,13214083:Words,[(48,32)(27,32)])
}
Add(Memory,12488741,238,70)
{
link(onData,2930488:doLength,[])
}
Add(Replace,599815,196,70)
{
SubStr="ё"
DestStr="е"
link(onReplace,12488741:doValue,[])
}
Add(Length,2930488,287,70)
{
link(onLength,12699095:doFor,[])
}
Add(StrCat,11542966,679,70)
{
Point(doClear)
link(Str1,15851392:Var3,[(685,57)(717,57)(717,107)])
}
Add(Copy,15238147,385,70)
{
Count=1
link(onCopy,9368850:doConvert,[])
link(Str,12488741:Value,[(391,54)(278,54)(278,114)(244,114)])
}
Add(For,12699095,336,70)
{
Start=1
InData=0
link(onEvent,15238147:doCopy,[])
link(onStop,5466566:doEvent1,[(380,83)(380,125)])
}
Add(If_else,14683811,476,70)
{
Type=4
Op2=Integer(48)
link(onTrue,4813029:doCompare,[])
}
Add(Convertor,9368850,427,70)
{
Mode=3
link(onResult,14683811:doCompare,[])
}
Add(If_else,4813029,525,70)
{
Type=3
Op2=Integer(57)
link(onTrue,11910301:doWork2,[])
link(onFalse,10662565:doCompare,[])
}
Add(If_else,10662565,567,77)
{
Type=4
Op2=Integer(224)
link(onTrue,11910301:doWork3,[(613,83)])
}
Add(HubEx,11910301,609,63)
{
link(onEvent,16483446:doConvert,[])
}
Add(Convertor,16483446,630,70)
{
Mode=4
link(onResult,11542966:doStrCat,[])
}
Add(Hub,5466566,637,119)
{
link(onEvent1,3362924:doData,[])
link(onEvent2,11542966:doClear,[(665,132)(665,83)])
}
Add(GetDataEx,15851392,672,98)
{
link(Data,11542966:Result,[])
}
Add(BlockFind,12336616,140,70)
{
IncludeBlock=1
Delete=0
ReplaceStr=" "
StartBlock=" "
EndBlock=" "
link(onSearch,599815:doReplace,[])
link(onEndSearch,13214083:onEnd,[(178,83)(178,34)])
}
Add(FormatStr,11837915,98,70)
{
DataCount=1
Mask=" %1 "
link(onFString,12336616:doSearch,[])
}
Add(InfoTip,776614,91,42)
{
Info=#26:Разделение строки на слова|
Width=92
Height=123
}
Add(InfoTip,16505643,189,42)
{
Info=#47:Удаление всего, кроме 32 русских букв и 10 цифр|
Width=638
Height=123
}
Add(If_else,530170,728,119)
{
Type=5
Op2=String()
link(onTrue,10295050:doValue,[])
}
Add(Memory,10295050,777,119)
{
link(onData,13214083:onRes,[(838,125)(838,27)])
}
Add(DoData,3362924,679,119)
{
link(onEventData,530170:doCompare,[])
link(Data,15851392:Var2,[])
}
END_SDK
Add(StrCat,7756213,182,336)
{
Point(doClear)
link(Str1,7103707:Var3,[(188,324)(222,324)(222,394)])
link(Str2,2335369:Result,[])
}
Add(Hub,6118933,140,420)
{
link(onEvent1,6238956:doTrim,[])
link(onEvent2,7756213:doClear,[(168,433)(168,349)])
}
Add(Trim,6238956,195,420)
{
Char=" "
link(onTrim,11994204:doString,[])
link(Text,7103707:Var2,[])
}



Только не понял в каком месте у тебя убираются знаки? Просто думаю надо знаки менять на пробелы а затем уже удалять лишние пробелы. И еще хотелось бы чтобы от цифр не отрезались бы знаки а просто добавлялась звездочка.
карма: 0

0
Ответов: 8926
Рейтинг: 823
#7: 2009-05-22 15:11:09 ЛС | профиль | цитата
Pirr, в Вывеске написано: "Удаление всего, кроме 32 русских букв и 10 цифр", в том числе и пробелы. Чтобы включить знак "-", (код 45) надо чуть изменить схему: code_13402.txt, но в этом случае придётся на выходе ставить маску "-#*", чтобы пропускать минус перед цифрами и удалять его в остальных случаях.
Непонятно зачем в FormatStr вместо % 1 появилось " Pirr "
карма: 19

0
файлы: 1code_13402.txt [549B] [189]
Разработчик
Ответов: 26151
Рейтинг: 2127
#8: 2009-05-22 16:54:08 ЛС | профиль | цитата
Леонид писал(а):
вместо % 1 появилось " Pirr "

Хи, хи. Уже второй попался, Tad был первым.
карма: 22

0
Ответов: 16884
Рейтинг: 1239
#9: 2009-05-22 17:01:48 ЛС | профиль | цитата
nesco писал(а):
Хи, хи. Уже второй попался, Tad был первым.
Не надо мне первентства.
Первым был tsdima.

карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Разработчик
Ответов: 26151
Рейтинг: 2127
#10: 2009-05-22 17:05:06 ЛС | профиль | цитата
Tad писал(а):
Не надо мне первентства

На сегодня ты был первым.
карма: 22

0
Ответов: 16884
Рейтинг: 1239
#11: 2009-05-22 17:09:15 ЛС | профиль | цитата
Но выход есть.
На нужном сообщении нажимаешь "Правка" и копируешь с окна Редактора сообщений все что тебе нужно и без ошибок.
Вот тебе и Хи-хи.
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 409
Рейтинг: 17
#12: 2009-05-22 19:20:52 ЛС | профиль | цитата
Леонид писал(а):
в Вывеске написано: "Удаление всего, кроме 32 русских букв и 10 цифр", в том числе и пробелы. Чтобы включить знак "-", (код 45) надо чуть изменить схему: code_13402.txt, но в этом случае придётся на выходе ставить маску "-#*", чтобы пропускать минус перед цифрами и удалять его в остальных случаях.

Я понял, что ты буквы переводиш в цифры и затем удаляешь все кроме русских букв и цифр.
А переводить знаки в пробел нужно для того, чтобы если слова написаны вот так: подошва-резиновая, подошва_резиновая, подошва/резиновая то после удаления знаков слова сливаются подошварезиновая.
И наверно надо включить англиЦкий шрифт.

Леонид писал(а):
Непонятно зачем в FormatStr вместо % 1 появилось " Pirr "

Непонятно.
карма: 0

0
Ответов: 8926
Рейтинг: 823
#13: 2009-05-22 22:42:52 ЛС | профиль | цитата
Pirr, теперь понятно - это глюк форума: заменяет сочетания % 1 - % 4 на данные пользователя
Для замены знаков препинания надо десяток элементов Replace, а английские буквы добавить (коды 97-122) тоже просто, так же как и цифры двумя If-Else
карма: 19

0
Ответов: 409
Рейтинг: 17
#14: 2009-05-23 11:39:12 ЛС | профиль | цитата
Леонид писал(а):
Для замены знаков препинания надо десяток элементов Replace, а английские буквы добавить (коды 97-122) тоже просто, так же как и цифры двумя If-Else

Смотрю я на схему, и думаю... мы перемудрили слегка.
Надо наверно сделать как в начале было, плюс занести в некий масив знаки (не так их и много будет), а затем перебором масива подставлять эти знаки в элемент замены символов и менять их на пробел, а уже потом избавлятся от лишних пробелов.
В принцыпе знаки не сильно мешают в запросе, т.к. в BOLEAN MODE - знаки не учитываются. Тут главное вычленить слова из запроса и обрезать их по алгоритму.
карма: 0

0
Ответов: 8926
Рейтинг: 823
#15: 2009-05-23 12:00:11 ЛС | профиль | цитата
Pirr, 1000 и ещё один способ, и все имеют право на жизнь
карма: 19

0
15
Сообщение
...
Прикрепленные файлы
(файлы не залиты)