Filtering by a aggregation (like SQL having clause)


(Lucas Porto) #1

Hi all,
My question is quite simple I think.

I have the query below where I use two types of aggregations. The query works fine.

GET /testeagg/_search
{
  "aggregations": {
	"group_by_id": {
	  "aggregations": {	
             "sum_qtd_item": {
                  "sum": { "field": "activities.qtd_itens" }  }  
          }, 
  	  "terms": {"field": "id_single_profile", "order": {"sum_qtd_item": "desc"	}  }
	}
  }, 
  "ext": {}, 
  "query": {  "match_all": {} }, 
  "size": 0
}

My output:

"aggregations": {
    "group_by_id": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": 555,
          "doc_count": 1,
          "sum_qtd_item": {
            "value": 6
          }
        },
        {
          "key": 999,
          "doc_count": 1,
          "sum_qtd_item": {
            "value": 6
          }
        },
        {
          "key": 123,
          "doc_count": 1,
          "sum_qtd_item": {
            "value": 3
          }
        },
        {
          "key": 666,
          "doc_count": 1,
          "sum_qtd_item": {
            "value": 0
          }
        }
      ]
    }
  }

All I need to do now is apply an filter in aggregation value (like we used to do by using HAVING clause in SQL).
For example, return all the keys with sum(activities.qtd_itens) > 3.

I tried to use filter+range without success. I don't know where is the exactly place I need to put the line below.
"filter": { "range": { "sum_qtd_item": { "gte": 3 } } }

I'll appreciate if anyone can help me with this.

Thanks!


(Shane Connelly) #2

Have a look at the bucket selector aggregation


(Lucas Porto) #3

Thanks man! Bucket selector worked for me.

But It was needed to change the type of a field. The "activities" is a nested field now. So I need to do the necessary changes in my query.

Do I need to use the "nested" tag as a new aggregation form? Or between one of my existing aggs?

Here's my query:

GET testeagg/_search
{
  "aggregations": {
    "group_by_id": {
      "aggregations": {
        "sum_qtd_item": {
          "sum": {
            "field": "activities.qtd_itens"
          }
        },
        "sales_bucket_filter": {
          "bucket_selector": {
            "buckets_path": {
              "sum_qtd_item": "sum_qtd_item"
            },
            "script": "params.sum_qtd_item >= 1"
          }
        }
      },
      "terms": {
        "field": "id_single_profile",
        "order": {
          "sum_qtd_item": "desc"
        }
      }
    }
  },
  "ext": {},
  "query": {
    "match_all": {}
  },
  "size": 0
}

Thanks!


(Lucas Porto) #4

I just found a solution here.

Here's my query final version.

GET /audience-3c9b46e4-1b10-4ad4-9a68-ae371034adfe/_search
{
  "aggs": {
    "group_by_id_single_profile": {
      "terms": {
        "field": "id_single_profile", "size": 10000
      },
      "aggs": {
        "nested_field": {
          "nested": {
            "path": "activities"
          },
          "aggs": {
            "sum_field": {
              "sum": {
                "field": "activities.qt_items"
              }
            }
          }
        },
        "FindIt": {
          "bucket_selector": {
            "buckets_path": {
              "sum_field": "nested_field>sum_field"
            },
            "script": "params.sum_field >= 5 && params.sum_field <= 10"
          }
        }
      }
    }
  },
  "query": {
    "nested": {
      "path": "activities",
      "query": {
         "bool": {
            "should": [
            { "match": { "activities.ds_action":  "Comprou" }},
            { "match": { "activities.nm_product": "Edição 115 anos - 13/10/2018"   }}
            ]
      }
    }
  }
  },
  "size": 0
}

(system) #5

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.