Elasti c Поиск составной группировки с диапазоном - PullRequest
1 голос
/ 15 марта 2020

Считайте, что следующие документы находятся в моем поиске c. Я хочу сгруппировать документы на основе ранга, но любой ранг ниже 1000 должен отображаться индивидуально, а все, что выше 1000, должно быть сгруппировано. Как мне добиться этого с помощью составной агрегации, я новичок и использую составную, потому что я хочу использовать после ключевая функция, чтобы позволить нумерацию страниц.

Documents 

    {
        rank : 200,
        name:abcd,
        score1 :100,
        score2:200
    },
    {
        rank 300,
        name:abcd,
        score1:100,
        score2:200
    }
Expected Result:
{
   key:{
    rank:101
   },
   doc_count:1,
   _score1: {value:3123}
   _score2 : {value :3323}
}
{
   key:{
    rank:1000-*
   },
   doc_count:1,
   _score1: {value:3123}
   _score2 : {value :3323}
},
   {
   key:{
    rank:300
   },
   doc_count:1,
   _score1: {value:3123}
   _score2 : {value :3323}
}

######## QUery that I tried

{
    "query":{"match_all":{}},
    "aggs":{
        "_scores":{
            "composite"{
                "sources":[
                    {"_rank":{"terms":{"field":"rank"}}}
                ]
            }
        },
        "aggs":{
            "_ranks":{
                "field":"rank:[
                    {"to":1000},
                    {"from":1000}
                ]
            }
            "_score1": {"sum": {"field": "score1"}}
            "_score2": {"sum": {"field": "score2"}}
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 15 марта 2020

Из того, что я понимаю, вы хотите

  • Группировать агрегаты, значение которых ниже 1000 ранга, по их собственным сегментам
  • Группировать агрегаты, значение которых составляет 1000 и выше, по один контейнер с ключом 1000-*
  • И для каждого контейнера рассчитайте сумму _score1 всех контейнеров
  • Аналогичным образом рассчитайте сумму _score2 всех контейнеров

Для этого сценария вы можете просто использовать Термины агрегации , как я уже упоминал в ответе ниже.

Я упомянул пример отображения, образцы документов, запросы и ответы, чтобы вы имели ясность в происходящем.

Отображение:

PUT my_sample_index
{
  "mappings": {
    "properties": {
      "rank":{
        "type": "integer"
      },
      "name":{
        "type": "keyword"
      },
      "_score1": {
        "type":"integer"
      },
      "_score2":{
        "type": "integer"
      }
    }
  }
}

Образцы документов:

POST my_sample_index/_doc/1
{
  "rank": 100,
  "name": "john",
  "_score1": 100,
  "_score2": 100
}

POST my_sample_index/_doc/2
{
  "rank": 1001,                        <--- Rank  > 1000
  "name": "constantine",
  "_score1": 200,
  "_score2": 200
}

POST my_sample_index/_doc/3
{
  "rank": 200,
  "name": "bruce",
  "_score1": 100,
  "_score2": 100
}

POST my_sample_index/_doc/4
{
  "rank": 2001,                        <--- Rank > 1000
  "name": "arthur",
  "_score1": 200,
  "_score2": 200
}

Запрос агрегации:

POST my_sample_index/_search
{
  "size":0,
  "aggs": {
    "_score": {
      "terms": {
        "script": {
          "source": """
            if(doc['rank'].value < 1000){
              return doc['rank'];
            }else
              return '1000-*';
          """
        }
      },
      "aggs":{
        "_score1_sum":{
          "sum": {
            "field": "_score1"
          }
        },
        "_score2_sum":{
          "sum":{
            "field": "_score2"
          }
        }
      }
    }
  }
}

Обратите внимание, что я использовал Агрегирование терминов по сценарию , где я упомянул в скрипте logi c. Логика c Я считаю, что это само собой понятно, когда вы go пройдете через это.

Ответ:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "_score" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "1000-*",             <---- Note this
          "doc_count" : 2,              <---- Note this
          "_score2_sum" : {
            "value" : 400.0
          },
          "_score1_sum" : {
            "value" : 400.0
          }
        },
        {
          "key" : "100",
          "doc_count" : 1,
          "_score2_sum" : {
            "value" : 100.0
          },
          "_score1_sum" : {
            "value" : 100.0
          }
        },
        {
          "key" : "200",
          "doc_count" : 1,
          "_score2_sum" : {
            "value" : 100.0
          },
          "_score1_sum" : {
            "value" : 100.0
          }
        }
      ]
    }
  }
}

Обратите внимание, что есть два ключа, имеющие rank > 1000, оба из которых набрали _score1 и _score2 сумму до 400, то есть ожидается.

Дайте мне знать, если это поможет!

0 голосов
/ 16 марта 2020

Я смущен ответом выше, но я думаю, что вы могли бы это иметь в виду. диапазон посещений https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-range-aggregation.html

...