我正在使用弹性搜索6.2.2的高级REST客户端。假设我在索引“DOCUMENTS”中有两个文档,类型为“DOCUMENTS”
{
"_id": 1,
"Name": "John",
"FunFacts": {
"FavColor": "Green",
"Age": 32
}
},
{
"_id": 2,
"Name": "Amy",
"FunFacts": {
"FavFood": "Pizza",
"Age": 33
}
}
我想找出所有独特有趣的事实及其独特的价值观,最终返回
的最终结果{
"FavColor": ["Green"],
"Age": [32, 33],
"FavFood": ["Pizza"]
}
这可以要求Elastic Search多个查询,但我更喜欢只有一个查询。此外,弹性搜索索引可能会变得相当大,因此我必须在ES实例上强制执行尽可能多的执行。
此代码似乎生成仅包含FunFacts
的文档列表,但我必须自己执行聚合,这是非常不可取。
SearchRequest searchRequest = new SearchRequest("DOCUMENTS");
searchRequest.types("DOCUMENTS");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
String [] includes = new String[1];
includes[0] = "FunFacts";
String [] excludes = new String[1];
excludes[0] = "Name";
searchSourceBuilder.fetchSource(includes, excludes);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse =
restHighLevelClient.search(searchRequest);
有人能指出我正确的方向吗?我注意到几乎所有的Elastic Search文档都以curl
命令的形式出现,这对我没有帮助,因为我不太精通将这些命令转换为JAVA。
这是你的情节扭曲。由于允许用户决定什么是他们有趣的事实,我们无法提前知道FunFacts
地图内的键是什么。 :/
谢谢, 马特
答案 0 :(得分:0)
您可以使用聚合在一个查询中完成所有操作。假设您的索引中包含以下文档
{
"Name": "Jake",
"FunFacts": {
"FavFood": "Burgers",
"Age": 32
}
}
{
"Name": "Amy",
"FunFacts": {
"FavFood": "Pizza",
"Age": 33
}
}
{
"Name": "Alex",
"FunFacts": {
"FavFood": "Burgers",
"Age": 28
}
}
,你想得到独特的" FavFood"选择,您可以使用以下术语聚合(docs on this topic)
{
"aggs": {
"disticnt_fun_facts": {
"terms": { "field": "FunFacts.FavFood" }
}
}
}
,这将导致这些行
{
...
"hits": { ... },
"aggregations": {
"disticnt_fun_facts": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "burgers",
"doc_count": 2
},
{
"key": "pizza",
"doc_count": 1
}
]
}
}
}
为了简洁起见,我只是将聚合部分留在了生成的响应上,因此需要注意的重要事项是存储桶数组,它代表找到的每个不同的术语, 密钥 ,以及文档中出现的次数 doc_count 。
希望有所帮助。