Привет! > А идея вашей проги такая же как у Димы? Т.е. если идет поиск по фразе, > то делается джойн таблицы на себя саму? Или же немного хитрее?
Ща спою :) Так вот, вкратце о задаче: имеется база нормативных актов (ну вообще-то это типа эталон, но у меня волосы дыбом встали, когда я увидел данные, которые надо было импортировать). Всего в базе около 70000 тысяч документов (примерно по 35к на каждом языке). Общий объем текстовых данных - с выкинутым форматированием HTML - около 700 метров, с форматированием - почти полтора гига. Документы имеют кучу всяких признаков - эмитент, источник публикации (не знаю как у вас, а у нас закон вступает в силу только после публикации в особом журнале - Официальном Мониторе), дату вступления в силу (он может вступать в силу через год, например) и кучу всяких параметров (гораздо больше, чем это выставленно наружу). Но самая большая проблема до сих пор была в том, что поиск по ключевым фразам делался только в заголовке и строго по введенному слову - т.е. там был обычный фуллскан на containing в заголовке (на мускуле). Перед нами была поставлена задача прикрутить туда полнотекстовый поиск (с некоторыми ограничениями, об этом ниже). Сейчас это все работает в тестовом режиме ( по адресу http://lex.justice.md/ можно увидеть, только переключить язык не забудьте). Сразу скажу, почему не прикрутили MnogoSearch - дело в том, что помимо вебовского интерфейса нам надо сделать прогу, с такой же мордой, но которую можно было бы юзать независимо от Инета - хотя обновляться, разумеется, по нему родимому придется. Прога под винду. Mnogosearch под винду во-первых платный (я хочу посмотреть, как наши госконторы заплатят за непонятно какую лицензию), во-вторых мы бы явно не влезли в бюджет, в-третьих я боялся, что мы банально не успеем прикрутить тот же MnogoSearch. Как решили. Взяли словарики румынского и русского языков (сейчас от ispell) и загнали их в базу - т.е. конструкция типа президент президента президенту президентом и т.д. была побита на пары (NF, WF1), (NF, WF2), ... где NF - контрольная сумма (CRC32) начальной формы ("президент"), а WFn - это контрольные суммы всех производных от начальной формы, допустимых по правилам конкретного языка. Итого, в словарике имеем почти миллион записей. Затем парсер разбивает очищенный документ на слова, слова меньше 3-х символов игнорируются (таким образом бОльшая часть слов-связок в румынском просто пропускается). Как непаханное поле для оптимизации мы оставили выкидывание всяких слов, которые не несут смысловой нагрузки, но больше 3-х символов (для русского языка, это будет "например", "потому" и т.д.). После этого, все варианты слов заменяются на нормальную форму для данного слова - разумеется, то, что не попадает в словарик (какой-нибудь специфический термин или слово, написанное с АшиПкой) - считается нормальной формой самого себя. Так как нам не требовалось хранить ВСЕ вхождения ВСЕХ слов во ВСЕ документы, то для каждого документа мы во-первых храним лишь количество таковых вхождений и первые три вхождения - позиции слов - чтобы можно было выкусывать цитаты. Это слегка позволило сэкономить количество поисковых индексов - всего, например, для документов на русском языке в телах документов содержится 15 768 228 слов (для румынского языка 18 528 190, но там слов-связок много больше) (имеется ввиду все вхождения - и нормальных форм и их производных), тогда как всего индексных записей - чуть более 12 000 000 для обоих языков - т.е. почти троекратная экономия за счет некоторого упрощения функциональности, которая в нашем случае нафиг не нужна. ФФсе, полнотекстовый поиск готов. Да, а где временные виртуальные таблицы? ;-) А вот где. Когда пользователь вводит ключевые слова, для каждого ключевого слова ищется его нормальная форма. В результате имеется набор чисел. И строится вот такой простой запрос (в качестве ключевых слов использовалось "президенту республики молдова" - регистр значения не играет), запрос уже с подставленными значениями, привожу первый из запросов, второй ничем, кроме списка полей вместо count() не отличается, кому интересно - гляньте в исходники страницы после выдачи результатов, они идут в виде комментариев: Подсчет количества найденных документов (ну вот захотелось им такую фичу и все): select count(d.id) from t_documents d, (select w.document_id, count(1) as cnt from t_search_words w, ( select 2624961196 as wrd from rdb$database union select 1902388292 as wrd from rdb$database union select 1228066714 as wrd from rdb$database ) t1 where w.lang_id=2 and w.flag=1 and w.word=t1.wrd group by 1 order by 2 desc ) idx where d.lang_id=2 and d.published_when>='01.07.2002' and d.published_when<='02.07.2007' and d.publisher_id =36149 and d.id=idx.document_id and idx.cnt=3 Тут все просто - виртуальную табличку, в которой содержатся слова для поиска объединяем с поисковыми индексами, а результат объединения - объединяем с таблицей с документами. Указание найти все три слова - последний and . Про то, что логически правильнее было бы использовать union all я знаю, но ключевые слова 2 раза не указывают. Если кто сможет указать более оптимальный вариант запроса - и такой же понятный - буду очень признателен. Пока же в самом худшем случае запрос исполняется секунд двадцать (первый запрос, пока система базу незакэшировала). Потом все летает пулей. У конкурентов слово Молдова ищется 5 минут (!!!). Размер базы - 2.5 Гига, на сервере памяти - 4Г. Некоторые параметры Птица изменены - если кого интересует, приведу полностью. Классик 2.0.1. Линух. Все, можно пинать ногами. З.Ы. 2 ДЕ или Влад - а лимит на количество записей в одной таблице сейчас какой? В релизнотах не нашел. -- Best regards, Sergey mailto:[EMAIL PROTECTED]