ElasticSearch: агрегационная фильтрация

Для простоты предположим, у меня есть индекс из 3-х строк в упругой:

{"id": 1, "tags": ["t1", "t2", "t3"]}, 
{"id": 2, "tags": ["t1", "t4", "t5"]}

Мне нужно агрегировать по некоторым тегам, не возвращая результат других тегов в соответствующих документах:

{
  "aggs": {
    "tags": {
      "terms": {"field": "tags"}
    }
  },
  "query": {
    "bool": {
      "filter": [
        {
          "terms": {"tags": ["t1", "t2"]}
        }
      ]
    }
  }
}

# RESULT
{
    "aggregations": {
        "tags": {
            "buckets": [
                {"doc_count": 2, "key": "t1"},
                {"doc_count": 1, "key": "t2"},
                {"doc_count": 1, "key": "t3"},  # should be removed by filter
                {"doc_count": 1, "key": "t4"},  # should be removed by filter
                {"doc_count": 1, "key": "t5"},  # should be removed by filter
            ],
        }
    },
    "hits": {
        "hits": [],
        "max_score": 0.0,
        "total": 2
    },
}

Как (возможно) постфильтровать этот результат?

Потому что в случае с 3 строками в индексе это только 3 лишних элемента (t3, t4, t5). Но в реальной ситуации у меня более 200 тысяч строк в индексе, и это ужасно! Мне нужно агрегировать по 50 тегов, но я получаю результат с более чем 1К тегами.

1 ответ

Решение

Предполагая, что ваша версия Elasticsearch поддерживает это, я должен использовать атрибут "include" для термина "агрегация". Ваш запрос должен быть таким, как указано выше:

POST /test/_search
{
  "aggs": {
    "tags": {
      "terms": {"field": "tags",  "include": ["t1", "t2"]}
    }
  },
  "query": {
    "bool": {
      "filter": [
        {
          "terms": {"tags": ["t1", "t2"]}
        }
      ]
    }
  }
}

`` `

Другие вопросы по тегам