Эластичный поисковый запрос для различных вложенных значений
Я использую REST-клиент высокого уровня для эластичного поиска 6.2.2. Предположим, что у меня есть два документа в индексе "ДОКУМЕНТЫ" с типом "ДОКУМЕНТЫ", которые
{
"_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
Карта.:/
Спасибо Мэтт
1 ответ
Вы можете сделать все это в одном запросе с помощью агрегатов. Предполагая, что у вас есть следующие документы в вашем индексе
{
"Name": "Jake",
"FunFacts": {
"FavFood": "Burgers",
"Age": 32
}
}
{
"Name": "Amy",
"FunFacts": {
"FavFood": "Pizza",
"Age": 33
}
}
{
"Name": "Alex",
"FunFacts": {
"FavFood": "Burgers",
"Age": 28
}
}
и вы хотите получить различные варианты "FavFood", вы можете сделать это, используя следующие агрегации терминов ( документы по этой теме)
{
"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
}
]
}
}
}
Для краткости я просто оставил часть агрегации в результирующем ответе, поэтому важно обратить внимание на массив buckets, который представляет каждый из найденных отдельных терминов, ключ и количество вхождений в ваших документах, doc_count.
Надеюсь, это поможет.