Как подсчитать количество повторений слова в каждом из документов индекса в ElasticSearch?

У меня есть индекс. Вот пример данных с индекса:

{
  "took" : 12,
  "timed_out" : false,
  "_shards" : {
    "total" : 20,
    "successful" : 20,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1834,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "profile_similarity",
        "_id" : "9c346fe0-253b-4c68-8f11-97bbb18d9c9a",
        "_score" : 1.0,
        "_source" : {
          "country" : "US",
          "city" : "Salt Lake City Metropolitan Area",
          "headline" : "Product Manager"
        }
      },
      {
        "_index" : "profile_similarity",
        "_id" : "e97cdbe8-445f-49f0-b659-6a19829a0a14",
        "_score" : 1.0,
        "_source" : {
          "country" : "US",
          "city" : "Los Angeles",
          "headline" : "K2 & Amazon, Smarter King, LLC."
        }
      },
      {
        "_index" : "profile_similarity",
        "_id" : "a7a69710-4fad-4b7d-88e4-bd0873e6fd03",
        "_score" : 1.0,
        "_source" : {
          "country" : "CA",
          "city" : "Greater Toronto Area",
          "headline" : "Senior Product Manager"
        }
      }
    ]
  }
}

Я бы хотел, чтобы по полям country, headline, мне выдавало еще количество повторений нужного мне слова. Например, если я ищу слово "US", вывод должен быть примерно таким:

{
  "took" : 12,
  "timed_out" : false,
  "_shards" : {
    "total" : 20,
    "successful" : 20,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1834,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "profile_similarity",
        "_id" : "9c346fe0-253b-4c68-8f11-97bbb18d9c9a",
        "_score" : 1.0,
        "_source" : {
          "country" : "US",
          "city" : "Salt Lake City Metropolitan Area",
          "headline" : "Product Manager",
          "country_count_US" : 1, 
          "headline_count_US" : 0
        }
      },
      {
        "_index" : "profile_similarity",
        "_id" : "e97cdbe8-445f-49f0-b659-6a19829a0a14",
        "_score" : 1.0,
        "_source" : {
          "country" : "US",
          "city" : "Los Angeles",
          "headline" : "K2 & Amazon, Smarter King, LLC.",
          "country_count_US" : 1, 
          "headline_count_US" : 0
        }
      },
      {
        "_index" : "profile_similarity",
        "_id" : "a7a69710-4fad-4b7d-88e4-bd0873e6fd03",
        "_score" : 1.0,
        "_source" : {
          "country" : "CA",
          "city" : "Greater Toronto Area",
          "headline" : "Senior Product Manager",
           "country_count_US" : 0, 
          "headline_count_US" : 0
        }
      }
    ]
  }
}

Возможно ли такое сделать средствами ElasticSearch? Если да - то как?

Если же выдать в таком формате мне результаты ElasticSearch не сможет, то буду благодарен за советы как это можно сделать в другом формате. Думаю, что мне подойдет решение в любом формате, лишь бы мы считали количество повторений нужного мне слова.

Благодарю за советы :)


Ответы (1 шт):

Автор решения: Сергей Храмов

Подсчеты в ElasticSearch есть и очень навороченные - аггрегации https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html

Судя по всему вам поможет такой запрос:

{
  "size": 0, // если нужен только подсчет
  "query": {***}, // ваш query, если не нужно считать абсолютно по всему
  "aggs": {
    "country_count": {
      "terms": { "field": "country" }
    },
    "headline_count": {
      "terms": { "field": "headline" }
    }
  }
}

Ответ будет примерно таким:

{
    "took": 12,
    "timed_out": false,
    "_shards": {
        "total": 20,
        "successful": 20,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1834,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": []
    },
    "aggregations": {
        "country_count": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [{
                    "key": "US",
                    "doc_count": 2
                },
                {
                    "key": "CA",
                    "doc_count": 1
                }
            ]
        },
        "headline_count": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [{
                    "key": "Product Manager",
                    "doc_count": 1
                },
                {
                    "key": "K2 & Amazon, Smarter King, LLC.",
                    "doc_count": 1
                }
            ]
        }
    }
}

Запросы можно вкладывать друг в друга, фильтровать и прочее. Обычно можно посчитать, что угодно.

→ Ссылка