Вызов! Сложный MySQL Query - PullRequest
2 голосов
/ 04 мая 2011

Мы кодируем небольшую поисковую систему.Таблицы базы данных:

Documents (DocumentID, Title, Abstract, Author, ...)
InvertedIndex (DocumentID, Word, Count)
Stopwords (Word)

Где InvertedIndex имеет запись для каждого слова в каждом документе и количество раз, которое оно появляется.Стоп-слова - это просто список слов, которые меня не волнуют.Движок запрашивается со списками терминов, разделенных или.Например:

  • term1 term2
  • term1 или term2
  • term1 term2 или term3

... и т. Д.Результаты поиска основаны на релевантности, рассчитанной для каждого документа с расширенной логической моделью.и-ed термины (все термины, которые не являются ored) умножаются, а ors суммируются.Например, учитывая запрос term1 term2 или term3, если термины появляются в документе 3, 4 и 5 раз соответственно, релевантность документа будет (3 * 4) +5 = 12. Кроме того, игнорируйте термины, которые существуют в стоп-словах..

Хорошо. Теперь ... мой профессор сказал нам, что вычисление релевантности для всех документов может быть выполнено одним запросом.Вот что мне нужно.

Я подготовил псевдокод для примера запроса term1 term2 или term3 .Вот так я бы рассчитал релевантность для каждого документа, но вместо этого я бы хотел выполнить один запрос MySQL.Я включил это так же, как пояснение для формулы релевантности.

foreach document
    relevance = 0
    foreach term_set // where (term1 term2) would be a term_set and (term3) would be the other
        product = 1
        foreach term
            if term not in stopwords
                SELECT Count FROM InvertedIndex WHERE Word=term AND DocumentID=document
                product *= Count
        relevance += product

(EXP (SUM (LOG (COALESCE (Column, 1)))) , по-видимому, является способом выполнения умножение совокупности .

Любая помощь будет принята с благодарностью. Извините, если это была тяжелая работа. Сейчас 2 часа, и я, вероятно, не очень хорошо объяснил это.

1 Ответ

1 голос
/ 05 мая 2011

Если я понимаю вашу проблему, это может помочь вам начать (но вам придется проверить синтаксис, так как мой MySQL ржавый):

Select DocumentId, Word, Count
From Documents
Inner Join InvertedIndex On Documents.DocumentID = InvertedIndex.DocumentID
Where Word In (term1, term2, term3)

Этот запрос даст вам список DocumentIds«поисковые» термины и количество для каждого документа, содержащего поисковый термин.Вы можете использовать это в качестве отправной точки для агрегирования по DocumentId, использования Group By DocumentId, а затем для определения вашей функции умножения агрегирования (которую я любезно оставляю вам).

Я недостаточно работал с MySQL, чтобызнаете, как исключить слова из таблицы стоп-слов (вы можете использовать EXCEPT в SQL Server), но что-то вроде этого может сработать:

Select DocumentId, Word, Count
From Documents
Inner Join InvertedIndex On Documents.DocumentID = InvertedIndex.DocumentID
Where Word In (term1, term2, term3)
And Where Not Exists (
    Select DocumentId, Word, Count
    From Documents
    Inner Join InvertedIndex On Documents.DocumentID = InvertedIndex.DocumentID
    Inner Join Stopwords On InvertedIndex.Word = Stopwords.Word
    Where Word In (term1, term2, term3)
)

Удачи в вашем назначении.Дайте нам знать, как это получается!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...