【无标题】

CSDN话题挑战赛第2期
参赛话题:Java技术分享

引言

优化一 :ES6.8.2 版本父子嵌套文档的三层聚合统计(空间换时间),将父文档需要聚合的字段,在子文档也多存一份,便于高基数的多层聚合

优化二 :ES6.8.2 版本没有Hash字段类型,通过引入插件 mapper-murmur3 插件实现
参考文档 https://developer.aliyun.com/article/801993

在高基数下,Hash字段类型的统计更占优势,但注意统计结果的 key 是哈希后的 值

为什么要使用这个技术?

提示:ES的父子嵌套文档(JOIN类型)是分开存储的,但可以保持字段一致,当存在需要分别聚合父文档指定字段,再聚合子文档指定多个字段的时候,可以用空间换时间的方式,将该字段数据在子文档多冗余存一份,当cardinality基数并不算高(未超过1W+)的场景下,有利于实现这种类型需求。
1,该技术的优点:支持超过size=1000 + 的桶聚合需求,支持ES 643 ~ ES 682的统计需求;
2,使用该技术后,既满足业务需求,又未浪费太多存储资源,且该种方式可复用,不受ES版本升级后的关于父子文档关联聚合 功能降低的影响;
如:增强了代码可读性和健壮性

技术案例,实战分享

提示:业务上存在一个需求,数据结构为父 join子文档类型,父文档为一条电商评论的主评论,子文档为该电商评论下的 标签文档,ES字段值和字段名参考如下 模板(template)

PUT _template/test_fuzi_msg
{
  "index_patterns": ["test_fuzi*"],
  "order" : 0,
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "_doc": {
      "properties": {
        "mid": {
          "type": "keyword"
        },
        "createdAt": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss"
        },
        "flag": {
          "type": "join",
          "eager_global_ordinals": true,
          "relations": {
            "MESSAGE": "COMMENT",
            "COMMENT": [
              "ASPECT",
              "COMMENT"
            ]
          }
        },
        "connectionId": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword"
              }
            }
          }
      }
    }
  }
}

> 数据量级
>![在这里插入图片描述] ![在这里插入图片描述](https://img-blog.csdnimg.cn/7b00a11e920944abb5337c8fb318e96a.jpeg#pic_center)

原查询在643版本上可用, 需要先统计父文档的 connectionId字段,再统计子文档的aspect字段,再统计每一个aspect标签的 正负面escore字段, 由于整体数据量过多,超过4000W,尽管 父文档的 connectionId 的基数不高,才 4000+ , 但在父子级关联查询存在缺陷的ES 682版本,这种统计相当耗时且 会超时。

ES的查询语句代码

#### 原语句1  ES682不支持统计 include过长
GET c22a603d22d24628a64631370e5e7ea3/_search
{
  "size" : 0,
  "query" : {
    "bool" : {
      "must" : [
        {
          "term" : {
            "flag" : {
              "value" : "COMMENT",
              "boost" : 1.0
            }
          }
        },
        {
          "range" : {
            "datetime" : {
              "from" : "2021-11-24 00:00:00",
              "to" : "2022-12-23 23:59:59",
              "include_lower" : true,
              "include_upper" : true,
              "format" : "yyyy-MM-dd HH:mm:ss",
              "boost" : 1.0
            }
          }
        }
  },
  "aggregations" : {
    "userConnectionIdTerms" : {
      "terms" : {
        "field" : "connectionId.keyword",
        "size" : 200,
        "min_doc_count" : 1,
        "shard_min_doc_count" : 0,
        "show_term_doc_count_error" : false,
        "order" : [
          {
            "_count" : "desc"
          },
          {
            "_term" : "asc"
          }
        ]
      },
      "aggregations" : {
        "aspectChildren" : {
          "children" : {
            "type" : "ASPECT"
          },
          "aggregations" : {
            "aspectTerms" : {
              "terms" : {
                "field" : "aspect2.keyword",
                "size" : 173,
                "min_doc_count" : 1,
                "shard_min_doc_count" : 0,
                "show_term_doc_count_error" : false,
                "order" : [
                  {
                    "_count" : "desc"
                  },
                  {
                    "_term" : "asc"
                  }
                ],
                "include" : [
                  "5G网络使用",
                  "Breeno(语音助手)",
                  "GPS",
                  "HeyTap大会员",
                  "HeyTap帐号",
                  "Hyper Boost加速引擎",
                  "OPPO+/OPPO社区",
                  "OPPO小游戏",
                  "OPPO金融",
                  "OPPO(HeyTap)支付",
                  "OSIE超清视效",
                  "TOF",
                  "USB调试",
                  "VOOC闪充移动电源",
                  "WiFi问题",
                  "logo",
                  "中框",
                  "主题商店",
                  "云服务",
                  "低质量应用",
                  "便签",
                  "信息",
                  "信息泄露",
                  "充电",
                  "充电方式",
                  "充电温度",
                  "充电速度",
                  "免打扰模式",
                  "全局搜索/下拉搜索",
                  "全屏多任务",
                  "兼容性类",
                  "内置软件其他问题",
                  "出厂标配(外观/品质)",
                  "出厂标配(错漏重)",
                  "分屏",
                  "加载类",
                  "升降结构",
                  "卡座",
                  "卡顿",
                  "发热",
                  "后台清理",
                  "听筒音效",
                  "呼吸灯",
                  "响铃/振动",
                  "图片/视频/音频类",
                  "基础ROM其他问题",
                  "声音效果",
                  "备份与恢复",
                  "天气",
                  "存储",
                  "安全其他问题",
                  "定屏",
                  "定时开关机",
                  "导航定位",
                  "导航键",
                  "屏保",
                  "屏功能类",
                  "屏外观类",
                  "屏幕",
                  "屏幕录制",
                  "屏幕背光时间/自动息屏时间",
                  "屏幕锁定",
                  "屏组件",
                  "屏触摸类",
                  "广告",
                  "应用分身",
                  "开关机类不良",
                  "开发者业务",
                  "录音",
                  "微信类",
                  "快充/闪充",
                  "快应用",
                  "快捷控制中心",
                  "恢复出厂设置",
                  "息屏时钟",
                  "悬浮球",
                  "截屏",
                  "手势体感",
                  "手感",
                  "手机管家",
                  "手电筒",
                  "扬声器",
                  "扬声器音效",
                  "折叠结构",
                  "护眼模式/夜间护眼",
                  "拨号",
                  "按键",
                  "按键类",
                  "接口",
                  "摄像头",
                  "支付类",
                  "收音机",
                  "数据丢失",
                  "数据网络其他问题",
                  "数据网络功能",
                  "整体外观",
                  "文件管理",
                  "新机激活引导",
                  "无线连接其他问题",
                  "日历",
                  "时钟",
                  "显示类",
                  "智能侧边栏",
                  "智能家居",
                  "智能手环",
                  "智能解锁",
                  "来电",
                  "来电归属地",
                  "查找手机",
                  "桌面类",
                  "游戏中心",
                  "游戏充值类",
                  "游戏其他问题",
                  "游戏内容",
                  "游戏功能类",
                  "游戏加速",
                  "游戏手柄",
                  "滑动结构",
                  "电子邮件",
                  "电池容量",
                  "电池续航",
                  "电池质量",
                  "电话本",
                  "电量管理",
                  "登录类",
                  "相册",
                  "相机",
                  "短视频",
                  "碰划伤",
                  "积分",
                  "系统升级异常",
                  "系统界面美观度",
                  "红包助手",
                  "结构其他问题",
                  "网速",
                  "耗电",
                  "耳机转接线",
                  "耳机音效",
                  "自带浏览器",
                  "自拍杆",
                  "蓝牙耳机",
                  "蓝牙音箱",
                  "解锁安全",
                  "计步类",
                  "计算器",
                  "话筒音效",
                  "语言和输入法",
                  "负一屏",
                  "车载闪充",
                  "软件商店下载/安装",
                  "软件商店其他问题",
                  "辅助功能/无障碍功能",
                  "运营商",
                  "进液",
                  "进灰/异物",
                  "远程守护",
                  "连接电脑",
                  "通信其他问题",
                  "通知中心与状态栏",
                  "通讯网络类",
                  "通话",
                  "配件其他问题",
                  "重启",
                  "钱包",
                  "锁屏杂志",
                  "闪退",
                  "阅读/书城",
                  "防摔",
                  "音乐播放",
                  "颜色",
                  "飞行模式",
                  "黑屏/自动关机",
                  "默认"
                ],
                "exclude" : [ ]
              },
              "aggregations" : {
                "escoreTerms" : {
                  "terms" : {
                    "field" : "escore",
                    "size" : 10,
                    "min_doc_count" : 1,
                    "shard_min_doc_count" : 0,
                    "show_term_doc_count_error" : false,
                    "order" : [
                      {
                        "_count" : "desc"
                      },
                      {
                        "_term" : "asc"
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}


GET c22a603d22d24628a64631370e5e7ea3/_search
{
  "aggs": {
    "connectionId_count": {
      "cardinality": {
        "field": "connectionId.keyword"
      }
    }
  }
}


结果:
"aggregations": {
    "connectionId_count": {
      "value": 4356
    }
  }

优化后语句

#### 方案 >>   使用子文档的connectionId 统计 - 优化HasChild 
GET c22a603d22d24628a64631370e5e7ea3/_search
{
  "size": 0,
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "flag": {
              "value": "COMMENT",
              "boost": 1
            }
          }
        },
        {
          "range": {
            "datetime": {
              "from": "2020-11-24 00:00:00",
              "to": "2022-12-23 23:59:59",
              "include_lower": true,
              "include_upper": true,
              "format": "yyyy-MM-dd HH:mm:ss",
              "boost": 1
            }
          }
        }
      ]
    }
  },
  "aggregations": {
    "aspectChildren": {
      "children": {
        "type": "ASPECT"
      },
      "aggregations": {
        "aspectFilter": {
          "filter": {
            "bool": {
              "must": [
                {
                  "terms": {
                    "aspect2.keyword": {
                      "index": "aspect_keyword_slow_es7",
                      "type": "_doc",
                      "id": "5",
                      "path": "aspect"
                    }
                  }
                }
              ]
            }
          },
          "aggs": {
            "userConnectionIdTerms": {
              "terms": {
                "field": "connectionId.keyword",
                "size": 100000,
                "min_doc_count": 1,
                "shard_min_doc_count": 0,
                "collect_mode": "breadth_first",
                "show_term_doc_count_error": false,
                "order": [
                  {
                    "_count": "desc"
                  },
                  {
                    "_term": "asc"
                  }
                ]
              },
              "aggregations": {
                "aspectTerms": {
                  "terms": {
                    "field": "aspect2.keyword",
                    "size": 126,
                    "min_doc_count": 1,
                    "shard_min_doc_count": 0,
                    "collect_mode": "breadth_first",
                    "show_term_doc_count_error": false,
                    "order": [
                      {
                        "_count": "desc"
                      },
                      {
                        "_term": "asc"
                      }
                    ]
                  },
                  "aggregations": {
                    "escoreTerms": {
                      "terms": {
                        "field": "escore",
                        "size": 4,
                        "execution_hint": "map",
                        "min_doc_count": 1,
                        "shard_min_doc_count": 0,
                        "show_term_doc_count_error": false,
                        "order": [
                          {
                            "_count": "desc"
                          },
                          {
                            "_term": "asc"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
其中filter部分的多个标签名,单独储存一个索引,使用数组类型;
"terms": {
                    "aspect2.keyword": {
                      "index": "aspect_keyword_slow_es7",
                      "type": "_doc",
                      "id": "5",
                      "path": "aspect"
                    }
                  }
###  1. 这里使用了模板_template
###  2. 利用ES的高效关联查询方式 look up
###  3. 统计结果测试 16G 8核的 两台 ES682版本的集群,测试 4300W数据的 结果为 5秒左右
PUT _template/aspect_keyword
{
  "index_patterns": ["aspect_keyword*"],
  "order" : 0,
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "_doc": {
      "properties": {
        "aspect": {
          "type": "keyword"
        },
        "createdAt": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss"
        }
      }
    }
  }
}

PUT aspect_keyword
GET aspect_keyword/_mapping

PUT aspect_keyword_test/_doc/4
{
  "createdAt": "2022-09-29 17:10:00",
  "aspect":"USB调试"
}

PUT aspect_keyword_slow_es7/_doc/5
{
  "createdAt": "2022-10-15 17:10:00",
  "aspect": [
            "音质好坏",
            "佩戴舒适程度",
            "做工",
            "电池续航",
            "外观颜值",
            "物流速度",
            "性价比",
            "主动降噪效果",
            "服务态度",
            "价格",
            "噪音",
            "佩戴稳定性",
            "颜色",
            "长时间佩戴舒适性",
            "蓝牙稳定性",
            "蓝牙连接速度",
            "包装精美度",
            "打假",
            "重量尺寸",
            "耳机品质",
            "物流包装完好性",
            "其他延迟",
            "材质",
            "通话效果",
            "耳机续航",
            "耳帽",
            "隔音效果",
            "耳机外观颜值",
            "退换货",
            "运动佩戴效果",
            "充电速度",
            "响应时间",
            "触控操作",
            "游戏延迟",
            "电影/游戏效果",
            "品控",
            "便携程度",
            "音量",
            "耳机适配性",
            "耐脏性",
            "充电盒续航",
            "音量调节",
            "漏音",
            "充电线/充电口",
            "APP",
            "智能功能",
            "磁吸开关",
            "操作功能",
            "佩戴重量",
            "弹窗快速配对连接",
            "耳机端操作",
            "耳机充电速度",
            "环境声模式",
            "按键操作",
            "充电盒外观颜值",
            "产品熟悉程度",
            "左右音量差异",
            "独立使用",
            "电量查看",
            "音频编码协议",
            "提示效果",
            "风噪",
            "耐磨损程度",
            "语音助手体验",
            "听诊器效应",
            "多个设备连接",
            "蓝牙配对速度",
            "防水性",
            "人声降噪效果",
            "无线充电",
            "种草/明星代言",
            "空间音频",
            "充电闪光灯指示",
            "左右电量差异",
            "拿取&盒子操作",
            "智能降噪",
            "配件缺失",
            "听歌、看视频延迟",
            "通话降噪",
            "生态",
            "电量显示",
            "按键品质",
            "APP兼容性",
            "OTA升级",
            "说明书",
            "充电盒充电速度",
            "降噪耳压",
            "操作自定义",
            "发声单元",
            "录音",
            "低音降噪效果",
            "软件功能",
            "材质类型",
            "产品防伪验真",
            "定位",
            "低电量提示",
            "降噪可调性",
            "降噪开关",
            "杜比音效",
            "来电提醒",
            "发热",
            "hi_res/小金标",
            "耳机发热",
            "降噪稳定性",
            "充电盒发热"
          ]
}

难点分析

提示:分析技术难点,通俗易懂的表达。
1、 父子文档的嵌套类型join本就存在一些问题,父子文档分开存储,关联的统计支持的量级很低,经过测试,上述语句最多支持 100Size的桶聚合;
2、当前业务的复杂程度在于,每篇文章的connnectionId基数并不高,所以统计上使用 keyword类型理论上应该可以完全支撑 ,但前提是最好在同一个索引中存储,才能比较好的支撑此种统计需求 ;
3、所以在子文档中,也存储父文档的对应 connnectionId,使得所有的统计聚合需求都在子文档中实现;
4、在现有业务基础上,优化长 terms查询,例如使用look up查询; 优化广度聚合,使用 “execution_hint”: "map"等方式,综合优化该调用接口;

技术小结

提示:学到了什么技术
在次优化过程中,主要弄清楚了ES对父子级结构支撑的有限性,通过空间换时间的方案,去解决通用性问题,且有尝试TEXT类型的fielddata=true属性;有尝试基于高基数的 Hash类型字段的处理方式
mapper-murmur3 插件实践一把

第一步:插件安装
bin/elasticsearch-plugin install mapper-murmur3
第二步:导入Demo测试
PUT my_index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "keyword",
        "fields": {
          "hash": {
            "type": "murmur3"
          }
        }
      }
    }
  }
}

提示:能够应用到什么场景等等。
主要应用于需要使用父结构的字段作为第一层桶,再来统计子结构文档的需求;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值