Grimson
Grimson

Reputation: 572

Elastic Search list of unique values of a field from Match query

I am using elastic search to get a list of all products of a kind (say camera), but I want to dynamically populate the list of manufacturers from the result I got from the match query.

{
  "query": {
    "match": {
      "product_type" : "CAMERA"
    }
  }
}

gives me a list of such items (after removing irrelevant data)

{
    "_score": 11.234668,
    "_source": {
        "product_type": "CAMERA",
        "mfg_name": "SONY"
    }
}

I can't aggregate all the mfg_name from the document as it would also contain manufacturers of other products as well. What I would like to do, get all the mfg_name for the product type I queried.

Is this natively supported by elastic search? Can I chain my queries such that output of match query is operated on by aggs query? Or do I have to write a service to go through the items one by one and get the list?

Edit: I use this to get the aggregate since Fielddata is disabled on text fields by default

{
"size": 0,
"aggs" : {
    "manufacturer" : {
        "terms" : { "field" : "mfg_name.keyword",  "size" : 500 }
    }
}}

Upvotes: 0

Views: 1440

Answers (1)

Carlos
Carlos

Reputation: 1431

You can aggregate the query results. Just need to write all in the same query.

Aggregation over the query results

Terms aggregation

You should index the mfg_name field as a non analyzed string in order to be able to do aggregations on that field. Otherwise you will get weird results like an aggregation for SON an another for ONY for instance.

Responding here to be able to paste code.

Update the index

PUT my_index {  "mappings": {
    "doc": { 
      "properties": { 
        "mfg_name":    { "type": "text"  }, 
        "mfg_name_na":     { "type": "text" , index: "not_analyzed" }
      }
    }
  }
}

I'm copying the mfg_name to a non analyzed field so you can do full text search over the original one, and then do aggregations over the non analyzed one.

Then reindex and you can query like this:

{
  "query": {
    "match": {
      "product_type": "CAMERA"
    }
  },
  "aggs": {
    "producers": {
      "terms": {
        "field": "mfg_name_na"
      }
    }
  }
}

You should receive a response containing a bucket aggregation with te desired data.

Upvotes: 1

Related Questions