Почему filterQuery не работает в REST-клиенте высокого уровня Elastic Search для JAVA?
Я пытаюсь создать функцию, выполняющую нечеткий поиск по индексу эластичного поиска. Я получаю совпадение только в том случае, если указываю термин точно так, как он написан в указателе. Если я намеренно неправильно написала одну букву в этом слове, например
"Бок"
, Я полагаю, что нечеткий поиск все равно должен возвращать то же совпадение, но вместо этого он не возвращает ничего. Аналогично, если я заменю fuzzyMatch на prefixQuery или termQuery, поиск вернет результат, только если задано точное написание
"Боб"
Почему это? Как это исправить? А где есть документация, объясняющая эти методы?
Вот мой код...
public void searchResults(@PathParam("index_name") String index_name) throws IOException {
RestHighLevelClient client = createHighLevelRestClient();
int numberOfSearchHitsToReturn = 100; // defaults to 10
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.fuzzyQuery("firstname", "Bob"));
sourceBuilder.from(0);
sourceBuilder.size(numberOfSearchHitsToReturn);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
SearchRequest searchRequest = new SearchRequest(index_name).source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.print(searchResponse);
client.close();
}
Вот результат Get /index/_search в Postman...
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "contacts",
"_type": "_doc",
"_id": "J1NDonABNQ4iHt4UOM4u",
"_score": 1.0,
"_source": {}
},
{
"_index": "contacts",
"_type": "_doc",
"_id": "153",
"_score": 1.0,
"_source": {
"firstname": "Bob",
"home_city": "San Diego",
"home_address": "1029 Loring Street",
"home_zip": "92109",
"contact_id": "153",
"email": "bsmith@gmail.com",
"lastname": "Smith",
"home_state": "California",
"cell_phone": "6192542981"
}
},
{
"_index": "contacts",
"_type": "_doc",
"_id": "154",
"_score": 1.0,
"_source": {
"firstname": "Alice",
"home_city": "Paia",
"home_address": "581 Pili Loko Street",
"home_zip": "00012",
"contact_id": "154",
"email": "aHernes@gmail.com",
"lastname": "Hernes",
"home_state": "Hawaii",
"cell_phone": "8083829103"
}
}
]
}
}
1 ответ
Я считаю, что резинка вас немного смущает.
Фаззин для трехбуквенного термина равен 1, так что вполне справедливо, что вы ожидаете возврата "Боб". Однако я предполагаю, что вы используете стандартный анализатор, который по умолчанию использует фильтр "нижний регистр".
Таким образом, рассчитанное расстояние Левенштейна между "Boc" и "bob" равно 2, поэтому оно не возвращается.
Попробуйте ввести термин в нижнем регистре, и я уверен, что вернется "Боб".
// no results
{
"query": {
"fuzzy" : { "firstname" : "Boc" }
}
}
// "Bob" returned
{
"query": {
"fuzzy" : { "firstname" : "boc" }
}
}
Имеет ли это смысл?
Что касается вашего кода:
public void searchResults(@PathParam("index_name") String index_name) throws IOException {
RestHighLevelClient client = createHighLevelRestClient();
int numberOfSearchHitsToReturn = 100; // defaults to 10
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// "Boc".toLowerCase() or simply "boc"
sourceBuilder.query(QueryBuilders.fuzzyQuery("firstname", "Boc".toLowerCase()));
sourceBuilder.from(0);
sourceBuilder.size(numberOfSearchHitsToReturn);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
SearchRequest searchRequest = new SearchRequest(index_name).source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.print(searchResponse);
client.close();
}