Сумма макс на группу в Elasticsearch - PullRequest
1 голос
/ 22 апреля 2019

Я хочу найти сумму max для каждой группы в данных Elasticsearch. Например:

Данные:

id  | gId | cost
----|-----|------
1   |  1  | 20 
2   |  1  | 15
3   |  2  | 30 
4   |  1  | 30   *
5   |  2  | 40   *
6   |  1  | 20
7   |  2  | 30
8   |  3  | 45   *
9   |  1  | 10

Я использую sum_bucket для суммирования по максимуму для группы. Это мой запрос:

{
    "aggs": {
        "T1":{
            "terms": {
                "field": "gId",
                "size":3
            },
            "aggs":{
                "MAX_COST":{
                    "max": {
                        "field": "cost"
                    }
                }
            }
        },
        "T2":{
            "sum_bucket": {
                "buckets_path": "T1>MAX_COST"
            }
        }
    },
    "size": 0
}

Ответ на запрос

"T1": {
    "doc_count_error_upper_bound": 0,
    "sum_other_doc_count": 0,
    "buckets": [                     |
        {                            |
            "key": 1,                |
            "doc_count": 5,          |
            "MAX": {                 |
                "value": 30          |
            }                        |
        },                           |
        {                            | How can ignore this part to return
            "key": 2,                | from elasticsearch query response
            "doc_count": 3,          |
            "MAX": {                 |
                "value": 40          |
            }                        |
        },                           |
        {                            |
            "key": 3,                |
            "doc_count": 1,          |
            "MAX": {                 |
                "value": 45          |
            }                        |
        }                            |
    ]                                   
},
"T2": {
    "value": 115
}

T2.value - желаемый результат. Но я хочу, чтобы в результате запроса T1.buckets игнорировался из-за проблем с производительностью сети, потому что мои данные очень большие. Устанавливая T1.terms.size для определенного числа, только верхний номер результата эффекта в результате T2.value. Как можно игнорировать T1.buckets в результате запроса, который я пишу, или лучше суммировать запрос на Сумма макс для групповой проблемы?

Ответы [ 2 ]

1 голос
/ 22 апреля 2019

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

добавьте термин, который мог бы отличать T1 и T2, например, {"exist": {"field": "value"}}, предполагая, что вы можете использовать термин "exist" в качестве термина.

0 голосов
/ 23 апреля 2019

Вы можете использовать filter_path, чтобы вернуть только подмножество ответа

var searchResponse = client.Search<Document>(s => s
    .FilterPath(new[] { "T2.value" }) // paths to include in response
    .Aggregations(a => a
        // ... rest of aggs here
    )
);

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

var searchDescriptor = new SearchDescriptor<Document>()
    .Aggregations(a => a
        // ... rest of aggs here
    );

var searchResponse = client.LowLevel.Search<StringResponse>(
    "index", 
    "type",
    PostData.Serializable(searchDescriptor),
    new SearchRequestParameters
    {
        QueryString = new Dictionary<string, object>
        {
            ["filter_path"] = "T2.value"
        }       
    });

// do something with JSON string response
var json = searchResponse.Body;
...