danpaz / bodybuilder

An elasticsearch query body builder :muscle:
http://bodybuilder.js.org
MIT License
1.25k stars 128 forks source link

Is it possible to control the order of methods when chaining multiple? #300

Open teddieliljekvist opened 2 years ago

teddieliljekvist commented 2 years ago

I am trying to implement something that functions like post_filter, to be able to return aggregations not included in the filter. When I try to build a query with query, aggregations and filter, in that order, bodybuilder re-orders the methods and generates the filter before everything else.

Is it possible to achieve this result or something that functions the same way?

{
  "query": {
    "match": {
      "rvcategory": "kilim"
    }
  },
  "aggregations": {
    "agg_terms_rvcategory": {
      "terms": {
        "field": "rvcategory"
      }
    },
    "agg_terms_shape": {
      "terms": {
        "field": "shape"
      }
    }
  },
  "filter": {
    "term": {
      "shape": "rectangular"
    }
  },
  "size": 10,
  "from": 0
}
ferronrsmith commented 1 year ago
bodybuilder()
        .query("match", "rvcategory", "kilim")
        .filter('term', 'shape')
        .agg('terms', 'rvcategory')
        .agg('terms', 'shape')
        .size(10)
        .from(0)
        .build()
frantvesson101 commented 1 year ago

It seems like you're encountering a challenge with the order of operations in your query. Have you considered using a nested aggregation within a filtered aggregation? This way, you can achieve the desired review result of returning aggregations not included in the filter. Here's an example structure you could try:

json Copy code { "query": { "match": { "rvcategory": "kilim" } }, "aggregations": { "filtered_agg": { "filter": { "term": { "shape": "rectangular" } }, "aggregations": { "agg_terms_rvcategory": { "terms": { "field": "rvcategory" } }, "agg_terms_shape": { "terms": { "field": "shape" } } } } }, "size": 10, "from": 0 } This way, the agg_terms_rvcategory and agg_terms_shape aggregations will be computed after applying the filter. Remember to adapt the field names to match your specific mapping.