Elasticsearch Rest High Level Client агрегирует поля динамически - PullRequest
1 голос
/ 04 мая 2020

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

Из main () я звоню

buildSearchCriteria("1");

Здесь я устанавливаю тип агрегации и соответствующие значения:

public static void buildSearchCriteria(String... exceptionId) {

        SearchCriteria searchCriteria = new SearchCriteria();

        Map<String, List<FieldNameAndPath>> stringListMap = new HashMap<>();

        stringListMap.put("nested", asList(new FieldNameAndPath("nested", "recommendations",
                "recommendations", null, emptyList(), 1)));

        stringListMap.put("filter", asList(new FieldNameAndPath("filter", "exceptionIds", "recommendations.exceptionId.keyword",
                asList(exceptionId),
                asList(new NestedAggsFields("terms", "exceptionIdsMatch")), 2)));

        stringListMap.put("terms", asList(new FieldNameAndPath("terms", "by_exceptionId", "recommendations.exceptionId.keyword", null, emptyList(), 3),
                new FieldNameAndPath("terms", "by_item", "recommendations.item.keyword", null, emptyList(), 4),
                new FieldNameAndPath("terms", "by_destination", "recommendations.location.keyword", null, emptyList(), 5),
                new FieldNameAndPath("terms", "by_trans", "recommendations.transportMode.keyword", null, emptyList(), 6),
                new FieldNameAndPath("terms", "by_sourcelocation", "recommendations.sourceLocation.keyword", null, emptyList(), 7),
                new FieldNameAndPath("terms", "by_shipdate", "recommendations.shipDate", null, emptyList(), 8),
                new FieldNameAndPath("terms", "by_arrival", "recommendations.arrivalDate", null, emptyList(), 9)));

        stringListMap.put("sum", asList(new FieldNameAndPath("sum", "quantity", "recommendations.transferQuantity", null, emptyList(), 10),
                new FieldNameAndPath("sum", "transfercost", "recommendations.transferCost", null, emptyList(), 11),
                new FieldNameAndPath("sum", "revenueRecovered", "recommendations.revenueRecovered", null, emptyList(), 12)));

        System.out.println(stringListMap);


        searchCriteria.setStringListMap(stringListMap);
        aggregate(searchCriteria);
    }

Ниже приведена функция агрегирования, которая будет получить вышеуказанную информацию и запрос о сборках:

public static void aggregate(SearchCriteria searchCriteria) throws IOException {

            Map<String, List<FieldNameAndPath>> map = searchCriteria.getStringListMap();

            List<FieldNameAndPath>  nesteds = map.get("nested");
            List<FieldNameAndPath>  filter = map.get("filter");
            List<FieldNameAndPath>  terms = map.get("terms");
            List<FieldNameAndPath>  sums = map.get("sum");

            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

            AggregationBuilder aggregationBuilder = new SamplerAggregationBuilder("parent");


            nesteds.stream().forEach(l -> buildAggregations(l, aggregationBuilder));
            filter.stream().forEach(l -> buildAggregations(l,  aggregationBuilder));
            terms.stream().forEach(l -> buildAggregations(l,  aggregationBuilder));
            sums.stream().forEach(l -> buildAggregations(l, aggregationBuilder));


            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("index");
            searchRequest.types("type");
            sourceBuilder.aggregation(aggregationBuilder);
            searchRequest.source(sourceBuilder);
            System.out.println(searchRequest.source().toString());
    }

метод buildAggregations:

private static AggregationBuilder buildAggregations(FieldNameAndPath fieldNameAndPath , AggregationBuilder parentAggregationBuilder) {

        if(fieldNameAndPath.getAggType().equals("nested")){
            parentAggregationBuilder = AggregationBuilders.nested(fieldNameAndPath.getFieldName(), fieldNameAndPath.getFieldPath());
        }

        if(fieldNameAndPath.getAggType().equals("filter")){
            parentAggregationBuilder.subAggregation(AggregationBuilders
                    .filter(fieldNameAndPath.getFieldName(),
                            QueryBuilders.termsQuery(fieldNameAndPath.getNestedAggs()
                                    .stream().map(nestedAggsFields -> nestedAggsFields.getFieldName()).findFirst().get(), fieldNameAndPath.getFieldValues())));
        }

        if(fieldNameAndPath.getAggType().equals("terms")){
            parentAggregationBuilder.subAggregation(AggregationBuilders.terms(fieldNameAndPath.getFieldName())
                    .field(fieldNameAndPath.getFieldPath()));
        }

        if(fieldNameAndPath.getAggType().equals("sum")){
            parentAggregationBuilder.subAggregation(AggregationBuilders.
                    sum(fieldNameAndPath.getFieldName()).field(fieldNameAndPath.getFieldPath()));
        }
        return parentAggregationBuilder;

    }

Класс SearchCriteria:

@Data
public class SearchCriteria {
    Map<String, List<FieldNameAndPath>> stringListMap;
    private List<String> searchFields;
}

И поле DTO FieldNameAndPath:

public class FieldNameAndPath{
    private String aggType;
    private String fieldName;
    private String fieldPath;
    private List<String> fieldValues;
    private List<NestedAggsFields> nestedAggs;
    private int order;
}

И результат запроса из приведенного выше кода:

{
  "aggregations": {
    "parent": {
      "sampler": {
        "shard_size": 100
      },
      "aggregations": {
        "exceptionIds": {
          "filter": {
            "terms": {
              "exceptionIdsMatch": [
                "1"
              ],
              "boost": 1
            }
          }
        },
        "by_exceptionId": {
          "terms": {
            "field": "recommendations.exceptionId.keyword",
            "size": 10,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        },
        "by_item": {
          "terms": {
            "field": "recommendations.item.keyword",
            "size": 10,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        },
        "by_destination": {
          "terms": {
            "field": "recommendations.location.keyword",
            "size": 10,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        },
        "by_trans": {
          "terms": {
            "field": "recommendations.transportMode.keyword",
            "size": 10,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        },
        "by_sourcelocation": {
          "terms": {
            "field": "recommendations.sourceLocation.keyword",
            "size": 10,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        },
        "by_shipdate": {
          "terms": {
            "field": "recommendations.shipDate",
            "size": 10,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        },
        "by_arrival": {
          "terms": {
            "field": "recommendations.arrivalDate",
            "size": 10,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        },
        "quantity": {
          "sum": {
            "field": "recommendations.transferQuantity"
          }
        },
        "transfercost": {
          "sum": {
            "field": "recommendations.transferCost"
          }
        },
        "revenueRecovered": {
          "sum": {
            "field": "recommendations.revenueRecovered"
          }
        }
      }
    }
  }
}

Ожидаемый запрос:

{
  "size": 0,
  "aggregations": {
    "exceptionIds": {
      "nested": {
        "path": "recommendations"
      },
      "aggregations": {
        "exceptionIdsMatch": {
          "filter": {
            "terms": {
              "recommendations.exceptionId.keyword": [
                "1"
              ],
              "boost": 1
            }
          },
          "aggregations": {
            "by_exceptionId": {
              "terms": {
                "field": "recommendations.exceptionId.keyword",
                "size": 10,
                "min_doc_count": 1,
                "shard_min_doc_count": 0,
                "show_term_doc_count_error": false,
                "order": [
                  {
                    "_count": "desc"
                  },
                  {
                    "_key": "asc"
                  }
                ]
              },
              "aggregations": {
                "by_item": {
                  "terms": {
                    "field": "recommendations.item.keyword",
                    "size": 10,
                    "min_doc_count": 1,
                    "shard_min_doc_count": 0,
                    "show_term_doc_count_error": false,
                    "order": [
                      {
                        "_count": "desc"
                      },
                      {
                        "_key": "asc"
                      }
                    ]
                  },
                  "aggregations": {
                    "by_destination": {
                      "terms": {
                        "field": "recommendations.location.keyword",
                        "size": 10,
                        "min_doc_count": 1,
                        "shard_min_doc_count": 0,
                        "show_term_doc_count_error": false,
                        "order": [
                          {
                            "_count": "desc"
                          },
                          {
                            "_key": "asc"
                          }
                        ]
                      },
                      "aggregations": {
                        "by_trans": {
                          "terms": {
                            "field": "recommendations.transportMode.keyword",
                            "size": 10,
                            "min_doc_count": 1,
                            "shard_min_doc_count": 0,
                            "show_term_doc_count_error": false,
                            "order": [
                              {
                                "_count": "desc"
                              },
                              {
                                "_key": "asc"
                              }
                            ]
                          },
                          "aggregations": {
                            "by_sourcelocation": {
                              "terms": {
                                "field": "recommendations.sourceLocation.keyword",
                                "size": 10,
                                "min_doc_count": 1,
                                "shard_min_doc_count": 0,
                                "show_term_doc_count_error": false,
                                "order": [
                                  {
                                    "_count": "desc"
                                  },
                                  {
                                    "_key": "asc"
                                  }
                                ]
                              },
                              "aggregations": {
                                "by_shipdate": {
                                  "terms": {
                                    "field": "recommendations.shipDate",
                                    "size": 10,
                                    "min_doc_count": 1,
                                    "shard_min_doc_count": 0,
                                    "show_term_doc_count_error": false,
                                    "order": [
                                      {
                                        "_count": "desc"
                                      },
                                      {
                                        "_key": "asc"
                                      }
                                    ]
                                  },
                                  "aggregations": {
                                    "by_arrival": {
                                      "terms": {
                                        "field": "recommendations.arrivalDate",
                                        "size": 10,
                                        "min_doc_count": 1,
                                        "shard_min_doc_count": 0,
                                        "show_term_doc_count_error": false,
                                        "order": [
                                          {
                                            "_count": "desc"
                                          },
                                          {
                                            "_key": "asc"
                                          }
                                        ]
                                      },
                                      "aggregations": {
                                        "quantity": {
                                          "sum": {
                                            "field": "recommendations.transferQuantity"
                                          }
                                        },
                                        "transfercost": {
                                          "sum": {
                                            "field": "recommendations.transferCost"
                                          }
                                        },
                                        "revenueRecovered": {
                                          "sum": {
                                            "field": "recommendations.revenueRecovered"
                                          }
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
...