Создание предложений по поисковым запросам с помощью Whoosh?

У меня есть набор документов в индексе Whoosh, и я хочу предоставить функцию предложения условий поиска. Итак, если вы наберете «поп», могут появиться следующие предложения:

  • Попкорн
  • популярный
  • Папа Римский
  • Тополь фильм
  • поп-культура

У меня есть термины, которые должны появиться в качестве предложений, входящих в поле NGRAMWORDS в моем индексе, но когда я делаю запрос в этом поле, я получаю автозаполненные результаты, а не расширенные предложения, поэтому я получаю документы с тегом «поп-культура». ", но нет возможности показать этот термин пользователю. (Для сравнения, я бы сделал это в ElasticSearch, используя сопоставление завершения для этого поля, а затем использовал бы конечную точку _suggest для получения предложений.)

Я могу найти только примеры автозаполнения или исправления орфографии в документации или где-либо еще в Интернете. Можно ли каким-либо образом получить предложения поисковых запросов из моего индекса с помощью Whoosh?

Изменить: expand_prefix был столь необходимым указателем в правильном направлении. В итоге я использовал KEYWORD(commas=True, lowercase=True) для своего поля предложения и код, подобный этому, чтобы получить предложения в порядке наиболее часто встречающихся (expand_prefix и iter_prefix дадут их в алфавитном порядке):

def get_suggestions(term):
    with ix.reader() as r:
        suggestions = [(s[0], s[1].doc_frequency()) for s in r.iter_prefix('suggest', term)]
    return sorted(suggestions, key=itemgetter(1), reverse=True)

person babbageclunk    schedule 23.01.2015    source источник


Ответы (2)


Это не совсем то, что вы ищете, но, вероятно, может вам помочь:

reader = index.reader()
for x in r.expand_prefix('title', 'pop'):
  print x

Пример вывода:

pop
popcorn
popular

Обновить

Другой обходной путь — создать еще один индекс с ключевыми словами только в виде ТЕКСТА. И поиграйте с языком поиска. Чего я смог добиться:

In [12]: list(ix.searcher().search(qp.parse('pop*')))
Out[12]: 
[<Hit {'keywords': u'popcorn'}>,
 <Hit {'keywords': u'popular'}>,
 <Hit {'keywords': u'pope'}>,
 <Hit {'keywords': u'Popular Film'}>,
 <Hit {'keywords': u'pop culture'}>]
person Dmitry Nedbaylo    schedule 23.01.2015
comment
На самом деле, это очень похоже на то, что я ищу! Просто пробую. - person babbageclunk; 23.01.2015
comment
Хм - результаты, которые я получаю, выглядят так, как будто мне не следует использовать тип поля NGRAMWORDS. Если я использую это в одном из своих полей KEYWORD, он делает именно то, что мне нужно. - person babbageclunk; 23.01.2015
comment
Итак, проблема в том, что он не может предлагать многословные термины. Это похоже на функцию токенизатора. Я не понимаю, почему expand_prefix не работает с полями KEYWORD. Есть ли вариант, который я мог бы передать в поле, чтобы включить его? - person babbageclunk; 23.01.2015
comment
Спасибо! Я обновлю вопрос тем, что я использую. - person babbageclunk; 23.01.2015

Термин Частотные функции

Я хочу добавить к ответам здесь, что на самом деле в whoosh есть встроенная функция, которая возвращает первые «числовые» термины по частоте терминов. Он находится в документации whoosh.

whoosh.reading.IndexReader.most_frequent_terms(fieldname, number=5, prefix='')

tf-idf в зависимости от частоты

Кроме того, на той же странице документов, прямо над предыдущей функцией в whoosh docs – это функция, которая возвращает наиболее отличительные термины, а не наиболее часто встречающиеся. Он использует показатель tf-idf, который эффективно устраняет распространенные, но незначащие слова, такие как «the». Это может быть более или менее полезным в зависимости от того, что вы ищете. он имеет соответствующее название:

whoosh.reading.IndexReader.most_distinctive_terms(fieldname, number=5, prefix='')

Каждый из них будет использоваться следующим образом:

with ix.reader() as r:
    print r.most_frequent_terms('suggestions', number=5, prefix='pop')
    print r.most_distinctive_terms('suggestions', number=5, prefix='pop')

Многословные предложения

Кроме того, у меня были проблемы с предложениями из нескольких слов. Мое решение состояло в том, чтобы создать схему следующим образом:

fields.Schema(suggestions = fields.TEXT(),
              suggestion_phrases = fields.KEYWORD(commas=True, lowercase=True)

В поле suggestion_phrases commas=True позволяет хранить ключевые слова с пробелами и, следовательно, иметь несколько слов, а lowercase=True игнорирует заглавные буквы (это можно удалить, если необходимо различать термины, написанные с заглавной буквы, и термины, написанные без заглавной буквы). Затем, чтобы получить предложения как из одного, так и из нескольких слов, вы должны запустить most_frequent_terms() или most_distinctive_terms() в обоих полях. Затем объедините результаты.

person Phillip Martin    schedule 14.10.2015