013.Elasticsearch聚合统计简单操作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了013.Elasticsearch聚合统计简单操作相关的知识,希望对你有一定的参考价值。

参考技术A 如果不加from和size,默认搜索前10条数据

考虑这样的场景:

假设某个index中总共有6万条数据,有3个shard,每个shard上有2万条数据,3个shard分布再node01、node02、node03这3个节点,客户端请求分页查询,查询第1000页的10条数据,请求发送给node04这个节点,那么node04会把请求转发到shard所在的3个节点,由于请求是第1000页的10条数据,所以应该是第10001-10010条数据,注意,这里每个shard都会将自己的前10010条数据返回给node04节点,而不是每个shard将第10001-10010这10条数据返回给node04,所以node04会受到30030条数据,而不是30条,拿到这30030条数据后,再根据相关度、"_score"进行排序,最终取到满足要求的第1000页的10条数据。

所以,深度分页是有性能问题的,这个过程是占用大量的网络带宽,协调节点(node04)的内存和CPU资源,所以应该尽量避免深度分页搜索。

elasticsearch聚合操作——本质就是针对搜索后的结果进行group by,统计下分组结果,包括min/max/avg

分析

最后,我们还有一个需求需要完成:允许管理者在职员目录中进行一些分析。 Elasticsearch有一个功能叫做聚合(aggregations),它允许你在数据上生成复杂的分析统计。它很像SQL中的GROUP BY但是功能更强大。

+

 

举个例子,让我们找到所有职员中最大的共同点(兴趣爱好)是什么:

GET /megacorp/employee/_search
{
  "aggs": {
    "all_interests": {
      "terms": { "field": "interests" }
    }
  }
}

暂时先忽略语法只看查询结果:

{
   ...
   "hits": { ... },
   "aggregations": {
      "all_interests": {
         "buckets": [
            {
               "key":       "music",
               "doc_count": 2
            },
            {
               "key":       "forestry",
               "doc_count": 1
            },
            {
               "key":       "sports",
               "doc_count": 1
            }
         ]
      }
   }
}

我们可以看到两个职员对音乐有兴趣,一个喜欢林学,一个喜欢运动。这些数据并没有被预先计算好,它们是实时的从匹配查询语句的文档中动态计算生成的。如果我们想知道所有姓"Smith"的人最大的共同点(兴趣爱好),我们只需要增加合适的语句既可:

GET /megacorp/employee/_search
{
  "query": {
    "match": {
      "last_name": "smith"
    }
  },
  "aggs": {
    "all_interests": {
      "terms": {
        "field": "interests"
      }
    }
  }
}

all_interests聚合已经变成只包含和查询语句相匹配的文档了:

  ...
  "all_interests": {
     "buckets": [
        {
           "key": "music",
           "doc_count": 2
        },
        {
           "key": "sports",
           "doc_count": 1
        }
     ]
  }

聚合也允许分级汇总。例如,让我们统计每种兴趣下职员的平均年龄:

GET /megacorp/employee/_search
{
    "aggs" : {
        "all_interests" : {
            "terms" : { "field" : "interests" },
            "aggs" : {
                "avg_age" : {
                    "avg" : { "field" : "age" }
                }
            }
        }
    }
}

虽然这次返回的聚合结果有些复杂,但任然很容易理解:

3

 

  ...
  "all_interests": {
     "buckets": [
        {
           "key": "music",
           "doc_count": 2,
           "avg_age": {
              "value": 28.5
           }
        },
        {
           "key": "forestry",
           "doc_count": 1,
           "avg_age": {
              "value": 35
           }
        },
        {
           "key": "sports",
           "doc_count": 1,
           "avg_age": {
              "value": 25
           }
        }
     ]
  }

该聚合结果比之前的聚合结果要更加丰富。我们依然得到了兴趣以及数量(指具有该兴趣的员工人数)的列表,但是现在每个兴趣额外拥有avg_age字段来显示具有该兴趣员工的平均年龄。

2

 

即使你还不理解语法,但你也可以大概感觉到通过这个特性可以完成相当复杂的聚合工作,你可以处理任何类型的数据。

以上是关于013.Elasticsearch聚合统计简单操作的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB——聚合操作

执行聚合

mongoDB应用篇-mongo聚合查询

MongoDB——聚合管道之$group操作

MongoDB——聚合管道之$group操作

pandas 进阶