Извлекайте данные из Elasticsearch, используя агрегаты, значения которых содержат дефис

Я уже давно работаю над упругим поиском... Недавно я столкнулся с проблемой.

Я хочу сгруппировать по определенному столбцу в эластичном поисковом индексе. Значения для этого конкретного столбца имеют дефисы и другие специальные символы.

SearchResponse res1 = client.prepareSearch("my_index")
            .setTypes("data")
            .setSearchType(SearchType.QUERY_AND_FETCH)
            .setQuery(QueryBuilders.rangeQuery("timestamp").gte(from).lte(to))
            .addAggregation(AggregationBuilders.terms("cat_agg").field("category").size(10))
            .setSize(0)
            .execute()
            .actionGet();

    Terms termAgg=res1.getAggregations().get("cat_agg");

    for(Bucket item :termAgg.getBuckets()) {    
        cat_number =item.getKey();
        System.out.println(cat_number+"  "+item.getDocCount());
        }

Это запрос, который я написал для того, чтобы получить группу данных по столбцу "категория" в "my_index".

Вывод, который я ожидал после запуска кода:---

категория-1 10

категория-2 9

категория-3 7

Но вывод, который я получаю:

10 категория

1 10

категория 9

2 9

категория 7

3 7

Я уже пролистал несколько ссылок " Проблема с дефисом в поиске с помощью фильтра" и т.д.

Но не могу решить мою проблему с этими ответами.

Любая помощь будет оценена!!

2 ответа

Решение

Это потому что твой category поле имеет отображение строки по умолчанию, и это analyzedотсюда category-1 получает токены как два токена, а именно category а также 1, который объясняет результаты, которые вы получаете.

Чтобы предотвратить это, вы можете обновить свое отображение, включив в него подполе category.raw который будет not_analyzed с помощью следующей команды:

curl -XPUT localhost:9200/my_index/data/_mapping -d '{
    "properties": {
        "category": {
            "type": "string",
            "fields": {
                "raw": {
                    "type": "string",
                    "index": "not_analyzed"
                }
            }
        }
    }
}'

После этого вам нужно будет переиндексировать ваши данные, и ваша агрегация сработает и вернет вам то, что вы ожидаете. Просто убедитесь, что изменили следующую строку в вашем коде Java:

.addAggregation(AggregationBuilders.terms("cat_agg").field("category.raw").size(10))
                                                                      ^
                                                                      |
                                                                add .raw here

Когда вы индексируете "категорию-1", вы получите (по умолчанию) два термина: "категория" и "1". Поэтому, когда вы объединяете, вы получите два результата для этого.

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

Другие вопросы по тегам