2016-10-12 2 views
1

Это результат вложенного запроса агрегации ES. Мне нужно разобрать этот ответ и преобразовать его в новый формат JSON. Из следующего JSON меня интересуют только те значения key_as_a_string и значение яблок и апельсинов для каждого ключа.Анализ ответа на вложенный ответ агрегации

"aggregations": { 
    "Inner_aggregation": { 
     "doc_count": 366, 
     "Hours_aggregation": { 
      "doc_count": 366, 
      "by_day": { 
       "buckets": [ 
        { 
         "key_as_string": "2016-01-11", 
         "key": 1452556800000, 
         "doc_count": 1, 
         "Apples": { 
          "value": 5 
         }, 
         "Oranges": { 
          "value": 3 
         } 
        }, 
        { 
         "key_as_string": "2016-01-12", 
         "key": 1452556800000, 
         "doc_count": 1, 
         "Apples": { 
          "value": 43 
         }, 
         "Oranges": { 
          "value": 2 
         } 
        }, 
        ........., 
        ......... 
       ] 
      } 
     } 
    } 
} 
} 

Я могу разобрать его с помощью Джексона ObjectMapper или с помощью sr.getAggregations(). Получить метод («histogram_name»), а затем итерация над коллекциями. Хотел узнать, есть ли там легкий путь.

формат JSON Обязательный

{ 
    "Results": [{ 
     "key_as_string": "2016-01-11", 
     "Apple_to_Orange_Ratio": 0.112 
    }, { 
     "key_as_string": "2016-01-12", 
     "Apple_to_Orange_Ratio": 0.12 
    }] 
} 

Ratio будет найден простым делением яблочного и апельсинового графа.

+0

Нет, это отклик интерфейса интерфейса, исходящий от кластера, вы не можете изменить формат ответа. Это весь смысл отдыха. Для перевода данных вам может понадобиться переводчик между вашим кластером и клиентом. – user3775217

ответ

1

Когда ваше представление Java сильно отличается от сложной вложенной структуры, бесполезно сопоставлять json непосредственно с Java-классами. Вы можете обрабатывать данные такого рода динамически.

Вот такой способ справиться с такими данными, используя Java 8 & библиотека Dynamics.

Мы разобрать JSON на структуру карты/список, и обернуть это в качестве динамического экземпляра

Map jsonMap = new ObjectMapper().readValue(exampleJson, Map.class); 
Dynamic jsonData = Dynamic.from(jsonMap); 

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

List<MyResult> results = jsonData 
    .dget("aggregations.Inner_aggregation.Hours_aggregation.by_day.buckets") 
    .children() 
    .map(bucket -> new MyResult(bucket)) 
    .collect(toList()); 

Теперь наш класс MyResult может обрабатывать данные в виде ведра, который также является динамическим экземпляром.

public class MyResult { 
    private final Dynamic bucket; 

    public Result(Dynamic bucket) { 
     this.bucket = bucket; 
    } 

    public String getKey() { 
     return bucket.get("key_as_string").asString(); 
    } 

    public double getAppleToOrangeRatio() { 
     double apples = bucket.dget("Apples.value").convert().intoDouble(); 
     double oranges = bucket.dget("Oranges.value").convert().intoDouble(); 
     return oranges/apples; 
    } 
} 

И мы можем получить доступ к отношениям.

double appleToOrangeRatio = results.get(0).getAppleToOrangeRatio(); 
// 0.6 

См. https://github.com/alexheretic/dynamics для источника, документации и примеров.