【问题标题】:Elastic Search composite grouping with range带范围的 Elastic Search 复合分组
【发布时间】:2020-06-26 20:17:15
【问题描述】:

考虑以下文档在我的弹性搜索中。我想根据排名对文档进行分组,但是必须单独显示任何低于 1000 的排名,并且必须对高于 1000 的任何排名进行分组我如何使用复合聚合来实现这一点,我是新手,我正在使用复合,因为我想使用 after允许分页的关键功能。

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"}}
        }
    }
}

【问题讨论】:

    标签: python json elasticsearch nosql


    【解决方案1】:

    据我了解,你想

    • 将值低于 1000 rank 的聚合分组到自己的存储桶中
    • 将值为1000及以上的聚合分组到一个带有键1000-*的单个桶中
    • 并且对于每个桶,计算所有桶的_score1之和
    • 同样计算所有桶的_score2之和

    对于这种情况,您可以简单地使用Terms Aggregation,正如我在下面的答案中提到的那样。

    我已经提到了示例映射、示例文档、查询和响应,以便您清楚地了解正在发生的事情。

    映射:

    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"
              }
            }
          }
        }
      }
    }
    

    请注意,我使用了Scripted Terms Aggregation,我在脚本中的逻辑中提到过。我相信,一旦你经历了它,逻辑是不言自明的。

    回应:

    {
      "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 &gt; 1000,它们的_score1_score2 的分数总和为400,这是预期的。

    如果这有帮助,请告诉我!

    【讨论】:

    • 这样的话,1000以下的部分根本不需要聚合
    • 我认为有必要。您假设只有一个带有rank=100 的文档,但可能有很多。用户还提到他想对_scores 求和,这又是一个聚合操作。例如,有两个排名为 100 的文档,您想将它们的分数相加。无论如何,如果他有更多疑问,我会让他回来。我的猜测是,他可能希望进一步对排名
    猜你喜欢
    • 2019-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 2018-01-14
    • 2015-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多