Combining Two Aggregations

Problem

I am currently trying to combine two aggregations into a single aggregation response either directly in ElasticSearch if it allows or In Java using the elastic aggregations as a map.

Elastic Approach

Mapping

"mappings": {
"properties": {
  "Career": {
    "type": "nested",
    "properties": {
      "Pro": {
        "type": "nested",
        "properties": {
          "teamName" :{
            "type": "keyword"
          },
          "position": {
            "type": "keyword"
          },
          "positionId": {
            "type": "keyword"
          },
          "positionsubtype": {
            "type": "keyword"
          },
          "positionsubtypeId": {
            "type": "keyword"
          }
        }
      },
      "College": {
        "type": "nested",
        "properties": {
          "teamName" :{
            "type": "keyword"
          },
          "position": {
            "type": "keyword"
          },
          "positionId": {
            "type": "keyword"
          },
          "positionsubtype": {
            "type": "keyword"
          },
          "positionsubtypeId": {
            "type": "keyword"
          }
        }
      },
      "High School": {
        "type": "nested",
        "properties": {
          "teamName" :{
            "type": "keyword"
          },
          "position": {
            "type": "keyword"
          },
          "positionId": {
            "type": "keyword"
          },
          "positionsubtype": {
            "type": "keyword"
          },
          "positionsubtypeId": {
            "type": "keyword"
          }
        }
      }
    }
  },
    "Name": {
      "type": "nested",
      "properties": {
        "Firstname": {
          "type": "keyword"
        },
        "Suffix": {
          "type": "keyword"
        },
        "Surname": {
          "type": "keyword"
        }
      }
    }
  }
}

Query

{
    "query": {
        "nested": {
            "path": "Name",
            "query": {
                "match": {
                    "Name.Firstname": "Odell"
                }
            }
        }
    },
    "aggs": {
        "Pro Career": {
            "nested": {
                "path": "Career.Pro"
            },
            "aggs": {
                "Positions": {
                    "terms": {
                        "field": "Career.Pro.position",
                        "size": 10
                    },
                    "aggs": {
                        "Position SubType": {
                            "terms": {
                                "field": "Career.Pro.positionsubtype",
                                "size": 10
                            }
                        }
                    }
                }
            }
        },
        "College Career": {
            "nested": {
                "path": "Career.College"
            },
            "aggs": {
                "Positions": {
                    "terms": {
                        "field": "Career.College.position",
                        "size": 10
                    },
                    "aggs": {
                        "Position SubType": {
                            "terms": {
                                "field": "Career.College.positionsubtype",
                                "size": 10
                            }
                        }
                    }
                }
            }
        }
    }
}

Response

"aggregations": {
        "Pro Career": {
            "doc_count": 2,
            "Positions": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "buckets": [
                    {
                        "key": "Wide Receiver",
                        "doc_count": 2,
                        "Position SubType": {
                            "doc_count_error_upper_bound": 0,
                            "sum_other_doc_count": 0,
                            "buckets": [
                                {
                                    "key": "First String",
                                    "doc_count": 2
                                }
                            ]
                        }
                    }
                ]
            }
        },
        "College Career": {
            "doc_count": 1,
            "Positions": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "buckets": [
                    {
                        "key": "Wide Receiver",
                        "doc_count": 1,
                        "Position SubType": {
                            "doc_count_error_upper_bound": 0,
                            "sum_other_doc_count": 0,
                            "buckets": [
                                {
                                    "key": "Second String",
                                    "doc_count": 1
                                }
                            ]
                        }
                    }
                ]
            }
        }
    }

Java Approach

public Map<String, Aggregation> combineAggregations() throws IOException {

    Collection<AggregationBuilder> aggregationBuilders = new ArrayList<>();
    aggregationBuilders.add(
            AggregationBuilders.nested("Pro Career","Career.Pro")
                    .subAggregation(AggregationBuilders.terms("Positions").field("Career.Pro.position")
                            .subAggregation(AggregationBuilders.terms("Positions SubType").field("Career.Pro.positionsubtype")
                                    .subAggregation(AggregationBuilders.topHits("Aggregation hit")))));
    aggregationBuilders.add(
            AggregationBuilders.nested("College Career","Career.College")
                    .subAggregation(AggregationBuilders.terms("Positions").field("Career.College.position")
                            .subAggregation(AggregationBuilders.terms("Positions SubType").field("Career.College.positionsubtype")
                                    .subAggregation(AggregationBuilders.topHits("Aggregation hit")))));

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    SearchRequest searchRequest = new SearchRequest();
    searchSourceBuilder.query(nestedQuery("Name", matchQuery("Name.Firstname","Odell"), ScoreMode.Avg));
    aggregationBuilders.forEach(searchSourceBuilder::aggregation);
    searchRequest.source(searchSourceBuilder).indices("player");
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
    Map<String,Aggregation> proAggregationMap = new HashMap<>();
    Map<String,Aggregation> collegeAggregationMap = new HashMap<>();

    searchResponse.getAggregations().getAsMap().forEach((s, aggregation) ->{
        if (s.equalsIgnoreCase("Pro Career")){
            Nested nested = (Nested) aggregation;
            nested.getAggregations().getAsMap().forEach(
                    proAggregationMap::put
            );
        }
        if (s.equalsIgnoreCase("College Career")){
            Nested nested = (Nested) aggregation;
            nested.getAggregations().getAsMap().forEach(
                    collegeAggregationMap::put
            );
        }
    });

    Map<String,Aggregation> careerAggregationMap = Stream.concat(
            proAggregationMap.entrySet().stream(),collegeAggregationMap.entrySet().stream()).collect(
            Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

    log.info(String.valueOf(careerAggregationMap));

    return careerAggregationMap;

}

Java Error

When merging the two Maps i get the current error as i currently don't have a merger to handle the two duplicate aggregations.

 java.lang.IllegalStateException: Duplicate key org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms@360938db

Any help to resolve this would be great

Thank you

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.