ElasticSearch — количество уникальных элементов во вложенном массиве

#elasticsearch

#elasticsearch

Вопрос:

Для упрощения понимания я покажу вам, как отображаются мои данные. Вот шаблон, который у меня есть.

 {
    "mappings": 
    {
        "properties": 
        {
            "applicationName": 
            {
                "type": "keyword"
            },
            "tags": 
            {
                "type": "nested",
                "properties": 
                {
                    "tagKey": 
                    {
                        "type": "keyword"
                    },
                    "tagKeyword": 
                    {
                        "type": "keyword"
                    }
                }
            }
        }
    }
}
 

Вот несколько примеров элементов,

 Sample item 1 
"applicationName": "application1"
"tags": [
         {"tagKey": "user", "tagKeyword": "aaa"},
         {"tagKey": "os", "tagKeyword": "android"}
        ]
 
 Sample item 2 
"applicationName": "application2"
"tags": [
         {"tagKey": "user", "tagKeyword": "bbb"},
         {"tagKey": "os", "tagKeyword": "ios"}
        ]
 
 Sample item 3
"applicationName": "application1"
"tags": [
         {"tagKey": "user", "tagKeyword": "aaa"},
         {"tagKey": "os", "tagKeyword": "pc"}
        ]
 

Я хочу получить количество отдельных tagKeyword, которые имеют tagKey «user» для каждого приложения.

Например,

 [
  {
    "applicationName": "application1",
    "distinctUser": 2
  },
  {
    "applicationName": "application2",
    "distinctUser": 1
  }
]
 

Оба решения или URL-адрес документа, связанные с этой проблемой, будут оценены по достоинству.

Ответ №1:

Вы можете использовать terms агрегацию для applicationName , а затем фильтровать пользовательские теги с помощью вложенной filter агрегации:

 POST index-name/_search?filter_path=aggregations.*.buckets.key,aggregations.*.buckets.nestedTags.distinctUser
{
  "size": 0,
  "aggs": {
    "distinctAppName": {
      "terms": {
        "field": "applicationName",
        "size": 10
      },
      "aggs": {
        "nestedTags": {
          "nested": {
            "path": "tags"
          },
          "aggs": {
            "distinctUser": {
              "filter": {
                "term": {
                  "tags.tagKey": "user"
                }
              }
            }
          }
        }
      }
    }
  }
}
 

выдача

 {
  "aggregations" : {
    "distinctAppName" : {
      "buckets" : [
        {
          "key" : "application1",
          "nestedTags" : {
            "distinctUser" : {
              "doc_count" : 2
            }
          }
        },
        {
          "key" : "application2",
          "nestedTags" : {
            "distinctUser" : {
              "doc_count" : 1
            }
          }
        }
      ]
    }
  }
}
 

Ответ №2:

Обратитесь к вложенным агрегациям. Попробуйте агрегировать термины для поля ApplicationName для группировки по приложениям, а затем выполните субагрегацию терминов для вложенных тегов полей.tagKeyword, чтобы получить отдельный список значений в данном приложении.

Также вам необходимо добавить фильтр для поля «tag.tagKey» как «user» в соответствии с вашими требованиями