ElasticSearch--aggregations聚合分析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElasticSearch--aggregations聚合分析相关的知识,希望对你有一定的参考价值。

聚合提供了从数据中分组和提取数据的能力。最简单的聚合方法大致等于SQL GROUPBY和SQL聚合函数。在Elasticsearch中, 您有执行搜索返回hits (命中结果),并且同时返回聚合结果,把一个响应中的所有hits (命中结果)分隔开的能力。这是非常强大且有效的,您可以执行查询和多个聚合,并且在一次使用中得到各自的(任何一个的)返回结果,使用次简洁和简化的API来避免网络往返。

聚合

GET /bank/_search

  "query": 
    "match": 
        "address": "mill"
    
  ,
  "aggs":  ## 聚合
    "ageAgg":   ## 聚合名字
    "terms": 
        "field": "age", ## 聚合属性
        "size": 10
      
    
  


返回结果

GET /bank/_search

  "query": 
    "match": 
        "address": "mill"
    
  ,
  "aggs":  ## 聚合
    "ageAgg":   ## 聚合名字
    "terms": 
        "field": "age", ## 聚合属性
        "size": 10
      
    ,
    "ageAvg": 查询平均值
      "avg": 
        "field": "age" ##年龄的
      
    
  ,
  "size": 0 ##只看 聚合结果

案例

查出所有年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资

GET /bank/_search

  "query": 
    "match_all": 
  ,
  "aggs": 
    "ageAgg": 
      "terms": 
        "field": "age",
        "size": 100
      ,
      "aggs": 
        "genderAgg": 
          "terms": 
            "field": "gender.keyword"
          ,
          "aggs": 
            "ageAvg": 
              "avg": 
                "field": "balance"
              
            
          
        ,
        "ageBalabceAvg":
          "avg": 
            "field": "balance"
          
        
      
    
  

Mapping映射

GET /bank/_mapping 查询类型

PUT /my-index

  "mappings": 
    "properties": 
      "age":     "type": "integer" ,  
      "email":   "type": "keyword"  , ## keyword 精确匹配 非全文检索
      "name":    "type": "text"       ## text 全文检索 非精确匹配 
    
  

不能直接修改映射 采用数据迁移

PUT /newbank

  "mappings": 
    "properties":  //具体规则
      "account_number": 
        "type": "long"
      ,
      "address": 
        "type": "text"
      ,
      "age": 
        "type": "integer"
      
      "gender": 
        "type": "keyword"
      ,
      "lastname": 
        "type": "keyword",
        "fields": 
          "keyword": 
            "type": "keyword",
            "ignore_above": 256
          
        
      
    
  


_reindex迁移
POST _reindex

  "source":  //迁移元数据
    "index": "bank",
    "type": "account"
  ,
  "dest":   //迁移新数据
    "index": "newbank"
  

编程技巧篇之特殊处理留痕迹

一、背景

在日常开发中需要有一些特殊处理的场景。

对于特殊处理的场景,建议留下标记,用来和正常的处理作区分。

二、举例


2.1 日志升级

为了方便排查问题,我们可以在 RPC 接口调用时,在上下文中传入某个标识符,如: debugToInfo = true
在日志工具类中,判断该标识,如果没有开启 DEBUG 级别,则提升为 INFO 级别。

参考伪代码如下:


public class LoggerUtil

  public static void debug(Logger logger, String... messages)
     // 如果原本支持 debug 日志,还是按照 debug 级别暑促
	if(logger.isDebugEnable())
	    logger.debug(messages);
	    return;
	
	
	// 开启 debug 提升到 info 日志时,打印 info 级别日志
	if(ContextUtils.openDebugToInfo() && logger.isInfoEnable())
 		logger.info(messages);
	    return;
    
  

日志示例:

DEBUG XX 业务,requst: xxx, result:yyy

为了标志特殊场景输出的日志,可以考虑将该情况的日志加上统一的前缀。

参考代码如下:


public class LoggerUtil
private static final String DEBUG_TO_INFO_LOG_HEAD ="【Debug2Info】 ";

  public static void debug(Logger logger, String... messages)
     // 如果原本支持 debug 日志,还是按照 debug 级别暑促
	if(logger.isDebugEnable())
	    logger.debug(messages);
	    return;
	
	
	// 开启 debug 提升到 info 日志时,打印 info 级别日志
	if(ContextUtils.openDebugToInfo() && logger.isInfoEnable())
 		logger.info(DEBUG_TO_INFO_LOG_HEAD,messages);
	    return;
    
  

日志示例:

INFO【Debug2Info】 XX 业务,requst: xxx, result:yyy

由于线上是 INFO 级别的日志,这个日志并不应该出现。
但我们看到 【Debug2Info】日志头时就很容易反映出来做了一些特殊处理。
这样可以清楚地知道这不是用户发起的请求,而是为了排查问题打印的日志。


2.2 属性标识

比如某个场景需要对一些推荐物品(直播、短视频、新闻、话题等)调用算法接口进行打分,由于某种特殊原因,某个投放物算法无法打分,需要临时通过代码对其中一类推荐物(如话题)随机打分。


items
// 过滤出话题的推荐物
.filter(ItemUtils::isTopic)
// t打分
.forEach(item -> item.setScore(RandomUtils.nextDouble(0,2)));

如果单纯这么处理,返回给前端的结果里 话题的数据和其他的数据打非常相似,单纯从结果里根本看不出是算法打分还是随机打分。

模拟示例如下:

["itemId":10086, "type":"video", score: 1.23
,"itemId":10088, "type":"video", score: 2.2
,"itemId":10288, "type":"topic", score: 1.4
,"itemId":10288, "type":"live", score: 1.024
]

按照本文提到的原则,特殊处理留痕,我们可以加一些附加属性。

items
// 过滤出话题的推荐物
.filter(ItemUtils::isTopic)
// 附加属性标志特殊处理
.peek( item -> ItemUtils.setAttr(item,"randomScore", true))
// 随机打分
.forEach(item -> item.setScore(RandomUtils.nextDouble(0,2)));

模拟示例如下:

["itemId":10086, "type":"video", score: 1.23
,"itemId":10088, "type":"video", score: 2.2
,"itemId":10288, "type":"topic", score: 1.4, "attr":"randomScore";true
,"itemId":10288, "type":"live", score: 1.024
]

这样就可以清楚地知道哪些推荐物做了特殊处理,后面去掉随机打分之后,该属性也不会再出现。

三、总结

对于需要特殊处理或者临时处理的场景下,尽量通过日志或者不影响正常业务的属性和常规数据标识出来,方便调试和排查问题。

想学习更多编程技巧,欢迎点赞、收藏加关注,未来持续更新更多文章。

以上是关于ElasticSearch--aggregations聚合分析的主要内容,如果未能解决你的问题,请参考以下文章