Forum Webscript.Ru
Общие => Базы данных => Тема начата: Error202 от 12 Декабря 2006, 14:14:59
-
Здравствуйте!
Есть таблицы MySQL:
words (слово, индекс слова)
docref (документ, индекс слова, позиция)
индекс слова - blob поле c 4-мя байтами
позиция - int, по ней нужно сортировать в порядке убывания
Задача: организовать поиск
Человек вводит фразу, она скриптом разбивается по словам и каждое слово заменяется на его индекс...
Мне нужно зная индексы слов вытащить все документы, в которых есть эти слова, да еще как-то отсортировать по "позиции"...
Помогите плз. если есть какие-нть идеи... Хотя бы без сортировки...
-
А версия?
-
Тестирую в 4.1.8, а работать будет на 4.1.14-log
-
Есть такая конструкция, но я не уверен, что она работает корректно:
SELECT document FROM docref
WHERE idx IN (\'AF5\', \'928\', \'FF71\',...)
GROUP BY document ORDER BY position DESC
-
Error202
может не стоит изобретать велосипед?
Full text index?
-
Error202
Действительно, что-то страшное замутил.
Но...
Вот допустим у тебя есть поисковая фраза.
1. Разбиваем на слова (напр., ваня курил траву)
2. Для каждого слова находим их индексы (напр., 365, 45, 897). Формируем строку типа $a=" \'365\', \'45\', \'897\' "
3. SELECT * FROM docref WHERE индекс слова IN ($a) SORT BY позиция
Правда чтобы отсортировать по количеству слов в доке и тем более релевантности, нужно что-то посолиднее
-
При релевантном поиске необходимо учитывать следующие моменты:
1. На этапе индексации необходимо просчитывать вес каждой леммы для каждого документа.
2. При поиске ключевой фразы, нужно найти все вхождения в индекс всех лемм.
3. Сортировку по релевантности нужно делать следующим образом:
Сначала выводить документы в которых находятся N слов из запроса с сортировкой по убыванию веса;
Далее искать документы в которых N-1 слов в той форме, которой они поступили, а 1 слово в возможных словоформах, потом N-2 и т.д.
После чего нужно сократить список слов до N-1 и произвести все выше указанные действия с этим множеством слов.
На всех этапах нужно сохранять полученные данные о весе документа, после произведённого поиска отсортировать данные в порядке убывания веса и выдать пользователю.
По поводу веса слов в коллекции http://ru.wikipedia.org/wiki/Tf-idf
Алгоритм ранжирования яндекса: http://romip.narod.ru/romip2006/03_yandex.pdf
Да и вообще почитайте http://romip.narod.ru/
Кроме того, на сайте searchengines.ru в форумах по поисковых технологиях есть очень интересные мысли: http://forum.searchengines.ru/forumdisplay.php?f=26
-
USE
Сначала выводить документы в которых находятся N слов из запроса с сортировкой по убыванию веса;
Далее искать документы в которых N-1 слов в той форме, которой они поступили, а 1 слово в возможных словоформах, потом N-2 и т.д.
После чего нужно сократить список слов до N-1 и произвести все выше указанные действия с этим множеством слов.
На всех этапах нужно сохранять полученные данные о весе документа, после произведённого поиска отсортировать данные в порядке убывания веса и выдать пользователю.
Здесь всё-таки есть варианты.
Например, я делал поиск в библиотеке Fanatica (http://fanatic.h16.ru/?a=search). Это поиск по БД. Там принцип такой.
1. Анализируется и обрабатывается сам запрос. Для каждого слова определяется его вес, в зависимости от его уникальности.
2. Создаётся массив слов запроса БЕЗ ОКОНЧАНИЙ И ПРИСТАВОК (то есть только корень + иногда суфифкс). Также создаётся массив слов в транслите (итого 3 массива)
3. Далее двойной цикл: проход по всем строкам данных (СД) + проход по всем массивам слов запроса (СЗ). Определяем, насколько СЗ совпадает с СД:
a) совпадает или нет
b) полное или нет вхождение СЗ в СД
c) встречается оно в начале или в середине слова
4. После проверки каждого слова увеличиваем общий К-релевантности данной СД на ВЕС СЛОВА * K-совпадения (последний зависит от пунктов 3b,3c).
5. Сортируем все строки данных по К-релевантности
Написал может непонятно, но работает очень даже неплохо. В верхних строчках самые точные вхождения.
Суть: важно обрабатывать сам запрос + считать релевантность по каждой строке и по каждому слову запроса
-
andymc:
Для каждого слова определяется его вес, в зависимости от его уникальности
На этапе поиска или индексации? По какому алгоритму определяется вес и уникальность?
andymc:
Создаётся массив слов запроса БЕЗ ОКОНЧАНИЙ И ПРИСТАВОК
Каким способом выделяется корень?
andymc:
создаётся массив слов в транслите
зачем?
-
На этапе поиска или индексации? По какому алгоритму определяется вес и уникальность?
На этапе поиска.
Пользователь делает запрос, например "скачать лекции по геометрии".
Производится стандартная обработка: нижний регистр, trim, убираем кавычки и др. спецсимволы, кроме точек.
Для определения веса слова вычисляется его уникальность. Она вычисляется на основе рейтинга уникальности слов (база данных слов и частоты их встречаемости). Например, "лекции" более частоупотребительное слово, чем "геометрии", значит и вес у них разный. Вес = максимальная частота в рейтинге - частота конкретного слова. Слова, которых вообще нет в рейтинговой базе, является самыми весомыми.
А такие слова как "скачать", "бесплатно" вообще удаляются из поиска.Каким способом выделяется корень?
Есть массив окончаний (ая, ий, я...) и приставок. Если они есть в данном слове запроса, они убираются. Как конкретно? Секрет :)
Например "геометрия" преобразуется в "геометр", что позволяет искать также слова "геометрический" и др.
Зачем транслит?
В общем-то он и не обязателен. Но дополнительно можно искать транслитированный вариант запроса. Только умножить вес данного запроса на коэффицент 1/2.
Прощу обратить внимание: это поиск не по документам, а по строкам из базы данных