0

I am trying to get my hands on javascript and elasticsearch and I was trying to create queries using the elastic-builder javascript lib. I might be missing something which I am trying to figure out but unfortunately I am unable to.

Problem: I am trying to create multilevel aggregation like below,

"aggs": {
    "1": {
      "date_histogram": {
        "field": "f1",
        "calendar_interval": "1D"
      },
      "aggs": {
        "2": {
          "date_histogram": {
            "field": "f2",
            "calendar_interval": "1D"
          },
          "aggs": {
            "3": {
              "date_histogram": {
                "field": "f3",
                "calendar_interval": "1D"
              }
            }
          }
        }
      }
    }

But what I get instead is this:

"aggs": {
    "1": {
      "date_histogram": {
        "field": "f1",
        "calendar_interval": "1D"
      },
      "aggs": {
        "2": {
          "date_histogram": {
            "field": "f2",
            "calendar_interval": "1D"
          }
        },
        "3": {
          "date_histogram": {
            "field": "f3",
            "calendar_interval": "1D"
          }
        }
      }
    }

The current output I get has two aggregations nested in one. I am trying to build it using an array with aggregations defined in it.

The code I used is below:

let a = [
    esb.dateHistogramAggregation('1', "d[key]['field']").calendarInterval('1D'), 
    esb.dateHistogramAggregation('2', "d[key]['field']").calendarInterval("1D"),
    esb.dateHistogramAggregation('3', "d[key]['field']").calendarInterval("1D")
];
let m = null;
for(i=0;i<a.length;i++) {
    if(i === 0) {
        m = a[i]
    } else {
        m.agg(a[i])
    }
}

//m = esb.dateHistogramAggregation('1', "d[key]['field']").calendarInterval('1D')
//m = m.agg(esb.dateHistogramAggregation('2', "d[key]['field']").calendarInterval("1D").agg(esb.dateHistogramAggregation('3', "d[key]['field']").calendarInterval("1D")))


esb.requestBodySearch()
    .query(
        esb.boolQuery()
            .must(esb.matchQuery('message', 'this is a test'))
            .filter(esb.termQuery('user', 'kimchy'))
            .filter(esb.termQuery('user', 'herald'))
            .should(esb.termQuery('user', 'johnny'))
            .mustNot(esb.termQuery('user', 'cassie'))
    )
    .agg(esb.termsAggregation('user_terms', 'user').agg(esb.termsAggregation('user_terms', 'user').agg(esb.termsAggregation('user_terms', 'user'))))
    .agg(m);

The lines commented in the code will output the result I'm expecting. What am I doing wrong?

2 Answers 2

1

You can turn the array into a group of sub-aggregations like so:

let a = [
    esb.dateHistogramAggregation('1', "d[key]['field']").calendarInterval('1D'), 
    esb.dateHistogramAggregation('2', "d[key]['field']").calendarInterval("1D"),
    esb.dateHistogramAggregation('3', "d[key]['field']").calendarInterval("1D")
];

const reqBody = esb.requestBodySearch()
    .agg(
        a[0].agg(
            a[1].agg(
                a[2]
            )
        )
    );
Sign up to request clarification or add additional context in comments.

2 Comments

I'm OK with this when I have just 3. But when it is dynamically generated then its a problem. I solved it but I don;t think its a proper way of solving it. I will post how I solved it. May be you can correct me there :)
Yes I was trying to use .agg.apply(null, a) but the lib doesn't support it.
1

I solved it like below. I am not sure this is right way. But someone can correct me if I am wrong.

    let temp = null;
    for (i = a.length - 1; i >= 0; i--) {
        if (i === a.length - 1) {
            temp = a[i];
        } else {
            temp = a[i].agg(temp)
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.