Я работаю над эластичным поиском уже довольно давно... Недавно я столкнулся с проблемой.
Я хочу сгруппировать по определенному столбцу в индексе эластичного поиска. Значения для этого конкретного столбца содержат дефисы и другие специальные символы.
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».
Результат, который я ожидал после запуска кода:
category-1 10
category-2 9
category-3 7
Но вывод, который я получаю:
category 10
1 10
category 9
2 9
category 7
3 7
Я уже рассмотрел некоторые вопросы, подобные этому, но не смог решить свою проблему с помощью этих ответов.
Решение проблемы
Это связано с тем, что ваше 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
Комментариев нет:
Отправить комментарий