Aggregeations with different keys and values (label and ID)

Dear ES community,

I hope someone can help me out with a (honestly) very basic question. I’m posting this because I couldn’t find a simple answer, to my surprise.

Let’s say I have a blog post indexed in ES (example below). Please note that the tags field contains both tag ID an label.

    {
        title: "Blog Post A",
        text: "…",
        tags: [
            {label: "Tag B", id: 1},
            {label: "Tag C", id: 2}
        ]
    }

My scheme looks like this, accordingly:

{
    title: { type: "text"  },
    text: { type: "text" },
    
    tags: {
        type: "nested",
        fields: {
            label: { 
                type: "text",
                fields: {
                    raw: {
                        type: "keyword"
                    }
                }
            },
            
            id: {
                type: "keyword"
            }
        }
    }
}


Here’s my problem: I’d like to aggregate blog posts by tag, displaying the tag’s label, but using the ID for filtering.
Using the ID would solve some issues in my multi-language environment.

My aggregation currently looks like the snippet below. My issue is that an aggregation like this doesn’t return the tag‘s ID.
What I’d need is one facet per tag, containing both ID and label.

Can anybody point me in a direction on how to do this?

Here’s my aggregation:

aggs: {
    tags: {
        terms: {
            field: "tags.label.raw" }
        }
    }
}

Hey,

so first, if you want to properly aggregate, you might also need the nested aggregation. Let's see if we can dig out a small example, where the ID is used for filtering.

DELETE test 

PUT test
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "text": {
        "type": "text"
      },
      "tags": {
        "type": "nested",
        "properties": {
          "label": {
            "type": "text",
            "fields": {
              "keyword" : {"type":"keyword"}
            }
          },
          "id": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

PUT test/_doc/1
{"tags":[{"label":"Tag B","id":1},{"label":"Tag C","id":2}]}

PUT test/_doc/2
{"tags":[{"label":"Tag B","id":1}]}

PUT test/_doc/3
{"tags":[{"label":"Tag B","id":2}]}

GET test/_search
{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "tags",
            "query": {
              "bool": {
                "filter": [
                  {
                    "term": {
                      "tags.id": "1"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "nested": {
      "nested": {
        "path": "tags"
      },
      "aggs": {
        "by_label": {
          "terms": {
            "field": "tags.label.keyword",
            "size": 10
          }
        }
      }
    }
  }
}

Also, if you specify examples/mappings, please use JSON syntax so one can easily try this out themselves

Ha! Thank you so much! I hadn’t checked the nested aggregation. That should do the job.
I’ll stick to JSON syntax next time.

1 Like

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