Как я могу сказать Solr, чтобы он возвращал поисковые запросы по каждому документу?

У меня вопрос по запросам в Solr. Когда я выполняю запрос с несколькими условиями поиска, которые все логически связаны оператором ИЛИ (например, q=content:(foo OR bar OR foobar)), Solr возвращает список документов, которые все соответствуют любому из этих условий. Но что Solr не возвращает, так это то, какие документы были затронуты какими терминами. Итак, в приведенном выше примере я хочу знать, какие документы в моем списке результатов содержат термин foo и т. Д. Имея эту информацию, я мог бы создать матрицу термин-документ.

Итак, мой вопрос: как я могу сказать Solr, чтобы он дал мне эту недостающую информацию? Я уверен, что он где-то есть, иначе поиск в целом не работал бы. Но что мне не хватает? Спасибо за вашу помощь.

PS: В качестве обходного пути я выполняю один запрос Solr для всех условий поиска. Но, как вы понимаете, это ужасно с точки зрения производительности, поскольку количество поисковых запросов может превышать 50 :(


person tbmsu    schedule 30.07.2014    source источник


Ответы (3)


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

Использовать выделение

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

Используйте информацию debugQuery

Вы можете проанализировать информацию, возвращаемую запросом, с debugQuery=true, чтобы определить, что термин был связан с результатом, посмотрев на termWeight (iirc). Это может быть отфильтрованная версия вашего исходного термина (если для этого поля активны основы и т. Д.).

Использовать сворачивание полей

Используя group.query, вы можете создавать списки документов, соответствующих каждому термину, вместо того, чтобы отправлять несколько запросов. Вы также можете создавать запросы, которые содержат несколько терминов, объединенных ИЛИ, если вам нужны списки для "содержит ни одного". Может оказаться неэффективным для большого количества полей.

Самостоятельно проанализируйте возвращенный документ

Получите документ, а затем извлеките условия самостоятельно. Потребуется немного нечеткого сопоставления, поскольку вам также придется иметь дело с обработкой текста на стороне Solr.

Использовать функциональные запросы

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

.. ни один из вариантов не идеален, но может помочь решить возникшую проблему.

person MatsLindh    schedule 30.07.2014
comment
Большое спасибо за быстрый ответ и интересные предложения. Теперь я использую функциональные запросы, и кажется, что производительность не является проблемой :) Для тех, кому интересно: я использую функциюexists и добавляю псевдополе для каждого поискового запроса, например: fl=exists(query({!v='content:(foo)'})),exists(query({!v='content:(bar)'})). Из ответа я анализирую поисковый запрос с помощью регулярного выражения. - person tbmsu; 31.07.2014
comment
@tbmsu Не могли бы вы опубликовать это в качестве ответа? Думаю, это поможет завершить пост. Также обратите внимание, что вы можете использовать псевдонимы псевдополя, чтобы избежать синтаксического анализа регулярных выражений, например fl=foo:exists(query({!v='content:(foo)'})) - person Paul Bellora; 02.10.2014
comment
Есть ли какое-нибудь решение, по которому я мог бы перечислить весь индекс поля данного документа? - person Shih-En Chou; 20.06.2015
comment
@ Shih-EnChou Комментарии - не место, чтобы задавать новые вопросы - создайте вопрос для этого. Чтобы увидеть необработанные токены для документа, используйте LukeRequestHandler, чтобы получить его в Solr, или инструмент Luke, чтобы проверить файлы индекса за пределами Solr. - person MatsLindh; 21.06.2015

Мой комментарий как ответ:

Я использую функциональные запросы, и кажется, что производительность не является проблемой :) Для тех, кому интересно: я использую функциюexists и добавляю псевдополе для каждого поискового запроса, например: fl=exists(query({!v='content:(foo)'})),exists(query({!v='content:(bar)'})). Из ответа я анализирую поисковый запрос с помощью регулярного выражения.

Как сказал выше Пол, вы можете использовать псевдонимы псевдополя, чтобы избежать синтаксического анализа регулярных выражений, например fl=foo:exists(query({!v='content:(foo)'}))

person tbmsu    schedule 02.10.2014
comment
Мне это пригодится, спасибо. Не могли бы вы сообщить мне, как я могу добавить более одного условия в этот локальный параметр? я пробовал `fl = foo: exists (query ({! v = 'content: (foo) and content2: (foo2)'})). Я тоже пробовал несколько вариантов, но, похоже, не работает. Любая идея? - person Ganesh; 28.10.2014
comment
Извините, что отправлено слишком рано, and должен быть в столице, чтобы это работало. В противном случае он рассматривается как строка, я думаю - person Ganesh; 28.10.2014

В моем случае solr6.6 запрос fl=foo:exists(query({!v='content:(foo)'})) не работает, он всегда возвращает 0 документов, а в моем документе было foo, поэтому мне нужно изменить этот запрос на ?q=*:*&fl=foo:exists(query({!v='content:(foo)'})), и я начал работать на себя.

person Root    schedule 05.10.2018
comment
Причина в том, что вы не включили запрос. fl не является запросом - это просто инструкция для Solr, сообщающая ему, какие поля он должен вернуть. Вы должны будете включить запрос, как вы обнаружили, где q=*:* вернет все документы в коллекции. - person MatsLindh; 05.10.2018