Question

How do I can run an aggregation query only on object property, but get all properties in result? e.g. I want to get [{'doc_count': 1, 'key': {'id': 1, 'name': 'tag name'}}], but got [{'doc_count': 1, 'key': '1'] instead. Aggregation on field 'tags' returns zero results.

Mapping:

{
  "test": {
    "properties" : {
      "tags" : {
        "type" : "object",
        "properties": {
          "id" : {"type": "string", "index": "not_analyzed"},
          "name" : {"type": "string", "index": "not_analyzed", "enabled": false}
        }
      }
    }
  }
}

Aggregation query: (returns only IDs as expected, but how can I get ID & name pairs in results?)

'aggregations': {
  'tags': {
    'terms': {
      'field': 'tags.id',
      'order': {'_count': 'desc'},
    },
  }
}

EDIT: Got ID & Name by aggregating on "script": "_source.tags" but still looking for faster solution.

Was it helpful?

Solution

you can use a script if you want, e.g.

"terms":{"script":"doc['tags.id'].value + '|' + doc['tags.name'].value"}

for each created bucket you will get a key with the values of the fields that you have included in your script. To be honest though, the purpose of aggregations is not to return full docs back, but to do calculations on groups of documents (buckets) and return the results, e.g. sums and distinct values. What you actually doing with your query is that you create buckets based on the field tags.id.

Keep in mind that the key on the result will include both values separated with a '|' so you might have to manipulate its value to extract all the information that you need.

OTHER TIPS

It's also possible to nest aggregation, you could aggregate by id, then by name.

Additional information, the answer above (cpard's one) works perfectly with nested object. Maybe the weird results that you got are from the fact that you are using object and not nested object.

The difference between these types is that nested object keeps the internal relation between the element in an object. That is why "terms":{"script":"doc['tags.id'].value + '|' + doc['tags.name'].value"} make sense. If you use object type, elasticsearch doesn't know which tags.name are with which tags.id.

For more detail: https://www.elastic.co/blog/managing-relations-inside-elasticsearch

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top