Python Whoosh — объединение результатов

Спасибо, что нашли время ответить на этот вопрос заранее. Я относительно новичок как в Python (3.6), так и в Whoosh (2.7.4), поэтому простите меня, если я упустил что-то очевидное.

Whoosh 2.7.4 — Ошибка объединения результатов

Я пытаюсь следовать инструкциям в документации Whoosh здесь, на Как искать > Объединение результатов. Однако я действительно потерялся в этом разделе:

# Get the terms searched for
termset = set()
userquery.existing_terms(termset)

Когда я запускаю свой код, он выдает эту ошибку:

Объект "set" не имеет атрибута "схема"

Что пошло не так?

Я также просмотрел документы об Whoosh API по этому вопросу, но Я просто больше запутался в роли ixreader. (Или это index.Index.reader()?) Пожимает плечами

Взгляд на мой код

Схема

schema = Schema(uid=ID(unique=True, stored=True),  # unique ID
                indice=ID(stored=True, sortable=True),
                title=TEXT,
                author=TEXT,
                body=TEXT(analyzer=LanguageAnalyzer(lang)),
                hashtag=KEYWORD(lowercase=True, commas=True,
                                scorable=True)
                )

Соответствующие имена полей — «хэштег» и «тело». Хэштеги — это выбранные пользователем ключевые слова для каждого документа, а тело — это текст в документе. Довольно очевидно, не так ли?

Функция поиска

Большая часть этого взята непосредственно из Whoosh Doc. Обратите внимание, что dic — это просто словарь, содержащий строку запроса. Кроме того, следует отметить, что ошибка возникает во время userquery.existing_terms(termset), поэтому, если все остальное — чушь, приношу свои извинения, я не дошел до этого.

try:
            ix = index.open_dir(self.w_path, indexname=lang)
            qp = QueryParser('body', schema=ix.schema)
            userquery = qp.parse(dic['string'])
            termset = set()
            userquery.existing_terms(termset)
            bbq = Or([Term('hashtag', text) for fieldname, text
                      in termset if fieldname == 'body'])
            s = ix.searcher()
            results = s.search(bbq, limit=5)
            allresults = s.search(userquery, limit=10)
            results.upgrade_and_extend(allresults)
            for r in results:
                print(r)
except Exception as e:
            print('failed to search')
            print(e)
            return False
finally:
            s.close()

Цель моего кода

Я беру страницы из разных файлов (pdf, epub и т. д.) и сохраняю текст каждой страницы как отдельный «документ» в индексе whoosh (т. е. в поле «тело»). Каждый «документ» также помечен уникальным идентификатором (uid), который позволяет мне брать результаты поиска и определять файл pdf, из которого они получены, и какие страницы содержат результат поиска (например, документ со страницы 2 «1.pdf "имеет uid 1.2). Другими словами, я хочу предоставить пользователю список номеров страниц, содержащих поисковый запрос, и, возможно, страницы с наибольшим числом совпадений. Для каждого файла единственным документом с хэштегами (или ключевыми словами) является документ с идентификатором пользователя, оканчивающимся на ноль (т. е. нулевая страница, например, идентификатор пользователя 1.0 для «1.pdf»). Нулевая страница может иметь или не иметь «тело» (например, дату публикации, имена авторов, резюме и т. д.). Я сделал это, чтобы предотвратить резкое повышение рейтинга одного документа с большим количеством страниц по сравнению с другим со значительно меньшим количеством страниц из-за многократного повторения ключевого слова в каждом «документе» (то есть странице).

В конечном счете, я просто хочу, чтобы код повышал уровень документов с хэштегом по сравнению с документами только с результатами поиска в основном тексте. Вместо этого я подумал о том, чтобы просто увеличить поле хэштега, но я не уверен, что это за механика, и документация не рекомендует этого делать.

Предложения и исправления будут приняты с благодарностью. Еще раз спасибо!


person juicyfruit    schedule 10.11.2017    source источник
comment
Ответ ниже отвечает на ваш вопрос?   -  person Steven    schedule 19.01.2020


Ответы (1)


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

try:
            ix = index.open_dir(self.w_path, indexname=lang)
            qp = QueryParser('body', schema=ix.schema)
            userquery = qp.parse(dic['string'])
            s = ix.searcher()
            allresults = s.search(userquery, limit=10)
            termset = userquery.existing_terms(s.reader())
            bbq = Or([Term('hashtag', text) for fieldname, text in termset if fieldname == 'body'])
            results = s.search(bbq, limit=5)

            results.upgrade_and_extend(allresults)
            for r in results:
                print(r)
except Exception as e:
            print('failed to search')
            print(e)
            return False
finally:
            s.close()

existing_terms требует reader, поэтому я сначала создаю searcher и передаю ему reader.

Что касается усиления поля, то механика достаточно проста< /а>:

schema = Schema(title=TEXT(field_boost=2.0), body=TEXT).

Добавьте достаточно высокий импульс, чтобы вывести документы с хэштегом на первое место, и обязательно примените один запрос как к полям основного текста, так и к полям хэштега.

Выбор между повышением или комбинированием зависит от того, хотите ли вы, чтобы все совпадающие документы с хэштегом всегда, абсолютно наверху, прежде чем будут показаны какие-либо другие совпадения. Если да, то комбинируйте. Если вместо этого вы предпочитаете соблюдать баланс релевантности, хотя и с более сильным уклоном в сторону хэштегов, повышайте.

person Steven    schedule 05.02.2019