Forum Webscript.Ru

Общие => Базы данных => Тема начата: Error202 от 12 Декабря 2006, 14:14:59

Название: Помогите с запросом... MySQL
Отправлено: Error202 от 12 Декабря 2006, 14:14:59
Здравствуйте!
Есть таблицы MySQL:

words (слово, индекс слова)
docref (документ, индекс слова, позиция)

индекс слова - blob поле c 4-мя байтами
позиция - int, по ней нужно сортировать в порядке убывания

Задача: организовать поиск

Человек вводит фразу, она скриптом разбивается по словам и каждое слово заменяется на его индекс...

Мне нужно зная индексы слов вытащить все документы, в которых есть эти слова, да еще как-то отсортировать по "позиции"...

Помогите плз. если есть какие-нть идеи... Хотя бы без сортировки...
Название: Помогите с запросом... MySQL
Отправлено: hanslinger от 12 Декабря 2006, 14:30:47
А версия?
Название: Помогите с запросом... MySQL
Отправлено: Error202 от 12 Декабря 2006, 14:39:55
Тестирую в 4.1.8, а работать будет на 4.1.14-log
Название: Помогите с запросом... MySQL
Отправлено: Error202 от 12 Декабря 2006, 16:16:13
Есть такая конструкция, но я не уверен, что она работает корректно:

SELECT document  FROM docref
WHERE idx IN (\'AF5\', \'928\', \'FF71\',...)
GROUP BY document  ORDER BY position DESC
Название: Помогите с запросом... MySQL
Отправлено: commander от 13 Декабря 2006, 14:21:40
Error202
может не стоит изобретать велосипед?
Full text index?
Название: Помогите с запросом... MySQL
Отправлено: andymc от 12 Января 2007, 00:54:37
Error202
Действительно, что-то страшное замутил.
Но...
Вот допустим у тебя есть поисковая фраза.
1. Разбиваем на слова (напр., ваня курил траву)
2. Для каждого слова находим их индексы (напр., 365, 45, 897). Формируем строку типа $a=" \'365\', \'45\', \'897\' "
3. SELECT * FROM docref WHERE индекс слова IN ($a) SORT BY позиция

Правда чтобы отсортировать по количеству слов в доке и тем более релевантности, нужно что-то посолиднее
Название: Помогите с запросом... MySQL
Отправлено: USE от 12 Января 2007, 13:50:52
При релевантном поиске необходимо учитывать следующие моменты:

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
Название: Помогите с запросом... MySQL
Отправлено: andymc от 12 Января 2007, 20:42:23
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. Сортируем все строки данных по К-релевантности

Написал может непонятно, но работает очень даже неплохо. В верхних строчках самые точные вхождения.

Суть: важно обрабатывать сам запрос + считать релевантность по каждой строке и по каждому слову запроса
Название: Помогите с запросом... MySQL
Отправлено: USE от 13 Января 2007, 16:01:53
Цитировать
andymc:
Для каждого слова определяется его вес, в зависимости от его уникальности

На этапе поиска или индексации? По какому алгоритму определяется вес и уникальность?
Цитировать
andymc:
Создаётся массив слов запроса БЕЗ ОКОНЧАНИЙ И ПРИСТАВОК

Каким способом выделяется корень?
Цитировать
andymc:
создаётся массив слов в транслите

зачем?
Название: Помогите с запросом... MySQL
Отправлено: andymc от 13 Января 2007, 18:38:10
Цитировать
На этапе поиска или индексации? По какому алгоритму определяется вес и уникальность?
На этапе поиска.
Пользователь делает запрос, например "скачать лекции по геометрии".
Производится стандартная обработка: нижний регистр, trim, убираем кавычки и др. спецсимволы, кроме точек.
Для определения веса слова вычисляется его уникальность. Она вычисляется на основе рейтинга уникальности слов (база данных слов и частоты их встречаемости). Например, "лекции" более частоупотребительное слово, чем "геометрии", значит и вес у них разный. Вес = максимальная частота в рейтинге - частота конкретного слова. Слова, которых вообще нет в рейтинговой базе, является самыми весомыми.
А такие слова как "скачать", "бесплатно" вообще удаляются из поиска.
Цитировать
Каким способом выделяется корень?
Есть массив окончаний (ая, ий, я...) и приставок. Если они есть в данном слове запроса, они убираются. Как конкретно? Секрет :)
Например "геометрия" преобразуется в "геометр", что позволяет искать также слова "геометрический" и др.

Зачем транслит?
В общем-то он и не обязателен. Но дополнительно можно искать транслитированный вариант запроса. Только умножить вес данного запроса на коэффицент 1/2.

Прощу обратить внимание: это поиск не по документам, а по строкам из базы данных