Почему FuzzyContext позволяет устанавливать префиксLength, но не использовать его?
Это ошибка интеграции Elasticsearch, но до сих пор об этом не сообщалось: спасибо!Мы попытаемся исправить это в следующем цикле разработки: HSEARCH-3545
Действительно ли стоит повышение производительности ES, чтобы попытаться включить prefixLength (я проверял вызовы запросов RESTнепосредственно к ES как с префиксом Length, так и без него и не заметил разницу во времени отклика)?
prefixLength
больше касается значимости результатов, чем производительности.Идея в том, что если пользователь даст нам слово длиной 10 символов, мы, скорее всего, получим множество нечетких совпадений, большинство из которых, вероятно, не имеют значения.Игнорируя первые 5 символов (например), мы сосредоточим размытость в конце слова, что, вероятно, менее актуально (например, «теория» / «теории», «составление» / «составление» и т. Д.):таким образом, мы получим меньше нечетких совпадений, но они будут более релевантными.
По крайней мере, это теория:)
Как я могу получить prefixLength для включения в реальный запросотправлено в ES?
Если вам не нужна поддержка нескольких токенов, вы можете создать FuzzyQuery
напрямую:
BooleanJunction namesBool = qb.bool();
String field = "vendorNames.vendorName";
String token = "rooster";
int editDistance = getEditDistance(token); //returns 1 for "rooster"
int prefixLength = getPrefixLength(token); //returns 1 for "rooster"
namesBool.must(
new FuzzyQuery(new Term(field, token), editDistance, prefixLength)
);
Этот запрос будет переведен правильно.
Если вам нужна поддержка нескольких токенов (т.е. вам нужен нечеткий match
запрос , а не просто fuzzy
запрос ), тогда ваше единственное решение будетнаписать запрос целом в формате JSON и использовать org.hibernate.search.elasticsearch.ElasticsearchQueries#fromJson
:
String field = "vendorNames.vendorName";
String token = "rooster";
int editDistance = getEditDistance(token); //returns 1 for "rooster"
int prefixLength = getPrefixLength(token); //returns 1 for "rooster"
QueryDescriptor queryDescriptor = ElasticsearchQueries.fromJson(
"{"
+ "\"query\": {"
+ "\"bool\": {"
+ "\"must\": {"
+ "\"match\": {"
+ "\"" + field + "\": {"
+ "\"query\": \"" + token + "\","
+ "\"fuzziness\": " + editDistance + ","
+ "\"prefix_length\": " + prefixLength
+ "}"
+ "}"
+ "}"
+ "}"
+ "}"
+ "}"
);
List<?> result = session.createFullTextQuery( queryDescriptor, MyEntity.class )
.list();
Да, это глоток ... Мы улучшаем вещи в Hibernate Search 6.