Почему 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();
}
Другие вопросы по тегам