Elasticsearch过滤最大值文档

时间:2016-02-18 19:25:42

标签: ruby ruby-on-rails-4 elasticsearch elasticsearch-rails

我试图从同名记录中获取文档的最大值。例如,我有3个用户,其中2个具有相同的名称但是不同的关注者数量,我想根据followers_count的最大值从2个相同的名称返回1个文档。

{ id: 1, name: "John Greenwood", follower_count: 100 }
{ id: 2, name: "John Greenwood", follower_count: 200 }
{ id: 3, name: "John Underwood", follower_count: 300 }

结果就是,

{ id: 2, name: "John Greenwood", follower_count: 200 }
{ id: 3, name: "John Underwood", follower_count: 300 }

从2个相同的名字中,拥有最多粉丝的人获胜,而其他单人也将来。

我的映射如下,

"users-development" : {
    "mappings" : {
      "user" : {
        "dynamic" : "false",
        "properties" : {
          "follower_count" : {
            "type" : "integer"
          },
          "name" : {
            "type" : "string",
            "fields" : {
              "exact" : {
                "type" : "string",
                "index" : "not_analyzed"
              }
            }
          },
        }
      }
    }

这是我长期被困的地方,

         {
            query: {
              filtered: {
                filter: {
                  bool: {
                    must: [
                      { terms: { "name.exact": [ "John Greenwood", "John Underwood" ] } },
                    ]
                  }
                }
              }
            },

            aggs: {
              max_follower_count: { max: { field: 'follower_count' } }
            },

            size: 1000,
          }

请提出任何建议

2 个答案:

答案 0 :(得分:2)

你的问题在弹性叠层中有一个特殊的工具,作为头部kkk的锤子。 是Aggregations,请参阅示例: 首先,在您的情况下,您需要使用包含空格的全名聚合,您的姓名字段需要not_analyzed这样

`PUT /index
{
  "mappings": {
    "users" : {
      "properties" : {
        "name" : {
          "type" :    "string",
          "index": "not_analyzed"
        }
      }
    }
  }
}`

现在您的查询将是这样的:

`POST /index/users/_search
{
   "aggs": {
      "users": {
         "terms": {
            "field": "name"
         },
         "aggs": {
            "followers": {
               "max": {
                  "field": "follower_count"
               }
            }
         }
      }
   }
}`

我只是按名称进行汇总,并使用最大metric来获得最高的关注者数。

回复将是这样的:

`"aggregations": {
      "users": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": "John Greenwood",
               "doc_count": 2,
               "followers": {
                  "value": 200
               }
            },
            {
               "key": "John Underwood",
               "doc_count": 1,
               "followers": {
                  "value": 300
               }
            }
         ]
      }
   }`

希望这对你有好处。 对需要汇总数据并获取值的总和的所有情况使用聚合。

答案 1 :(得分:0)

好的,我认为你正在寻找这些方面的东西,使用terms aggregation

{
   "query": {
      "terms": { "name.exact": [ "John Greenwood", "John Underwood" ] }
   },
   "aggs": {
      "max_follower_count": {
         "terms": {
            "field":"name.exact"
         },
         "aggs":{
             "max_follow" : { "max" : { "field" : "follower_count" } }
         }
      }
   },
   "size": 1000
}

术语聚合将为names.exact中的每个唯一值设置一个存储桶,该值仅为您在术语查询中指定的值。因此,我们现在为两个Johns都有一个存储桶,现在我们可以使用max聚合来计算谁拥有最多的关注者。 max聚合将在其父聚合中的每个存储桶上运行。

这些唯一术语中的每一个都将计算其最大值follower_count,并显示在存储桶中。结果如下:

... //query results of just the terms query up here
"aggregations": {
  "max_follower_count": {
     "doc_count_error_upper_bound": 0,
     "sum_other_doc_count": 0,
     "buckets": [
        {
           "key": "John Greenwood",
           "doc_count": 2,
           "max_follow": {
              "value": 200
           }
        },
        {
           "key": "John Underwood",
           "doc_count": 1,
           "max_follow": {
              "value": 300
           }
        }
     ]
  }
}

聚合这个术语带有一些关于如何进行计数的警告,并且链接的文档应该非常明确。