不同嵌套值的弹性搜索查询
Elastic Search Query for Distinct Nested Values
我正在使用 Elastic Search 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 进行多个查询是可以的,但我更喜欢只有一个查询。此外,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
地图中的键是什么。 :/
谢谢,
马特
您可以使用聚合在一个查询中完成所有操作。假设您的索引中有以下文档
{
"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
}
]
}
}
}
为了简洁起见,我只是在结果响应中留下了 aggregations 部分,因此需要注意的重要事项是 buckets 数组,代表找到的每个不同术语,key,以及它们在文档中出现的次数, doc_count.
希望对您有所帮助。
我正在使用 Elastic Search 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 进行多个查询是可以的,但我更喜欢只有一个查询。此外,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
地图中的键是什么。 :/
谢谢, 马特
您可以使用聚合在一个查询中完成所有操作。假设您的索引中有以下文档
{
"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
}
]
}
}
}
为了简洁起见,我只是在结果响应中留下了 aggregations 部分,因此需要注意的重要事项是 buckets 数组,代表找到的每个不同术语,key,以及它们在文档中出现的次数, doc_count.
希望对您有所帮助。