Elasticsearch показывает, что соответствует запросу - PullRequest
1 голос
/ 09 октября 2019

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

Допустим, у меня есть варианты:

  • Цвет : красный, синий, черный, желтый, зеленый
  • Размер : очень маленький, довольно средний, очень большой
  • Форма : круглая, квадратная, продолговатая, цилиндрическая
  • Год : 2007, 2008, 2009, 2010

Если вы введете «Очень маленькие звездочки 2007 года», в текстовом поле будет предложено «Искать все очень маленькие виджеты 2007 года« звездочки »». Она поняла, что «2007» и «очень маленький» были выбранными параметрами в форме, а «звездочками» не было, и предложила поиск, где выбраны «2007» и «очень маленький», а затем оставила «звезду»-pangled "бит для поиска в незашифрованном виде.

Сейчас я работаю над синтаксическим анализом поискового запроса и выделением битов, которые вписываются в поля выбора. У меня есть все варианты в Elasticsearch. Я думал о поиске каждого типа индивидуально, чтобы увидеть, соответствует ли он чему-либо в поисковом запросе. Это кажется простым для меня. Я могу легко найти совпадения. Однако я не знаю, какая часть запроса на самом деле соответствует каждому типу, что мне нужно для того, чтобы выяснить, что, например, «звездочками» - это та часть, которая не соответствует параметрам.

Итак,в конце мне нужно знать, что только подстрока "2007" соответствовала году, только "очень маленькая" подстрока соответствовала размеру, а "звездочками" ничего не соответствовало.

Мой первыймысль состоит в том, чтобы разбить запрос на грамматики слов (например, «2007», «очень 2007», «очень маленький 2007», «очень маленькая звездочка 2007 года», «очень», «очень маленькая», «очень маленькая звезда»). spangled "," small "," small star-spangled "," star-spangled ") и ищите каждый вариант для каждого грамма. Тогда я бы точно знал, какой грамм соответствует. Тем не менее, это, очевидно, может быстро потреблять ресурсы. Кроме того, я знаю, что Elasticsearch может выполнять такой поиск внутри компании намного быстрее.

Так что мне действительно нужно иметь возможность выполнять поиск и, вместе с результатами, возвращать, какая часть исходного запроса фактическисоответствует. Поэтому, если бы я искал «2007 verr small» (преднамеренное неправильное написание) и выполнял нечеткий поиск размеров, пропуская всю строку запроса, и в результате я получал обратно «Очень маленький» размер, это означало бы, что «verr small»та часть запроса, которая соответствует этому размеру.

Есть идеи, как это сделать? Или, возможно, какие-то другие решения?

Я мог бы выполнить поиск и проанализировать результаты, чтобы увидеть, какие биты соответствуют строке. Хотя я мог видеть, что это ресурсоемкий процесс. И если я выполняю нечеткий поиск, не обязательно будет ясно, какая часть запроса вызвала совпадение в результате.

Я также думал, что для этого может помочь выделение, но я нея не знаю достаточно о Elasticsearch, чтобы знать наверняка.

РЕДАКТИРОВАТЬ : Я проверил это с помощью выделения. Это так близко к работе. Поле выделения возвращается с той частью строки, которая соответствует. Однако он показывает только ту часть результата , которая соответствует. Он не показывает ту часть запроса , которая соответствует. Поэтому, если я хочу разрешить нечеткие поиски, поле выделения не будет соответствовать исходному запросу, и я не смогу определить, какая часть запроса соответствует. Например, запрос «very smaal» вернет размер «Very Small», но в поле выделения будет отображаться <em>very</em> <em>small</em>, а не <em>very</em> <em>smaal</em>.

1 Ответ

0 голосов
/ 10 октября 2019

В Elasticsearch есть 2 типа запросов: Соответствующий запрос и Отфильтрованный запрос . Запрос на совпадение соответствует вашему термину в документах и ​​находит все соответствующие документы с оценкой релевантности. Например, при поиске термина «помощь в устранении проблемы с JavaScript» вас интересуют все документы, содержащие один или несколько поисковых терминов.

С другой стороны, когда вы используете фильтрованный запрос, документэто либо совпадение, либо не совпадение ... здесь нет оценки релевантности ... например, вам нужны все продукты, выпущенные в году "2007" ... здесь вам нужно использовать отфильтрованный запрос. Все продукты, выпущенные в 2007 году, имеют одинаковую оценку, и все остальные годы исключаются из результата.

По моему мнению, ваша проблема должна решаться с помощью Filter Query ...

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

enter image description here

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

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

Если вы хотите придерживаться одного поля поиска, не реализуйте функциональность фильтра и придерживайтесь Elasticsearch Multi-match query .. . вы можете сопоставить входной термин в нескольких полях, но вы не сможете отфильтровать (исключить) результат, вместо этого вы получите оценку релевантности.

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