主要知识点:

  • 直接对分词的term进行聚合后果
  • 设置fielddata=true
  • 直接用.keyword进行聚合
  • doc value 的性能问题

     
     

一、直接对分词的term进行聚合后果

 
 

对于分词的field执行aggregation,发现报错。。。

 
 

1、新建一条数据(隐式创建一个索引和type)

 
 

POST /test_index/test_type/1

{

"test_field":"test"

}

 
 

2、进行聚合操作

 
 

GET /test_index/test_type/_search

{

"aggs": {

"group_by_test_field": {

"terms": {

"field": "test_field"

}

}

}

}

 
 

执行结果如下:

{

"error": {

"root_cause": [

{

"type": "illegal_argument_exception",

"reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [test_field] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory."

}

 
 

对分词的field直接执行聚合操作es会报错,错误信息中会说,必须要打开fielddata(fielddata=true),然后将正排索引数据加载到内存中,才可以对分词的field执行聚合操作,而且会消耗很大的内存

 
 

二、设置fielddata=true

1、给分词的field,设置fielddata=true

 
 

POST /test_index/_mapping/test_type

{

"properties": {

"test_field": {

"type": "text",

"fielddata": true

}

}

}

 
 

2、查看mapping

GET /test_index/_mapping/test_type

 
 

执行结果

{

"test_index": {

"mappings": {

"test_type": {

"properties": {

"test_field": {

"type": "text",

"fields": {

"keyword": {

"type": "keyword",

"ignore_above": 256

}

},

"fielddata": true

}

}

}

}

}

}

 
 

3、再次执行聚合操作

GET /test_index/test_type/_search

{

"size": 0,

"aggs": {

"group_by_test_field": {

"terms": {

"field": "test_field"

}

}

}

}

执行结果如下:

"aggregations": {

"group_by_test_field": {

"doc_count_error_upper_bound": 0,

"sum_other_doc_count": 0,

"buckets": [

{

"key": "test",

"doc_count": 2

}

]

}

}

}

可以看出如果要对分词的field执行聚合操作,必须将fielddata设置为true

 
 

三、直接用.keyword进行聚合

1、使用内置field不分词,对string field进行聚合。在es新版本中,新对text的字段新建一个.keyword的字段,可以直接用这个字段进行聚合操作

 
 

GET /test_index/test_type/_search

{

"size": 0,

"aggs": {

"group_by_test_field": {

"terms": {

"field": "test_field.keyword"

}

}

}

}

执行结果如下:

"aggregations": {

"group_by_test_field": {

"doc_count_error_upper_bound": 0,

"sum_other_doc_count": 0,

"buckets": [

{

"key": "test",

"doc_count": 2

}

]

}

}

}

可以看出此时就已经可以聚合。如果对不分词的field执行聚合操作,直接就可以执行,不需要设置fieldata=true

 
 

四、分词field+fielddata的工作原理

在es内部会对所有不分词的field建立doc value,这些不分词的field可以执行聚合操作,如果某一个field不分词,那么在新建index的时候就已经建立了doc value值,所以es针对不分词的field会自动使用doc value来执行聚合操作。

对于分词field,是没有doc value的,在新建索引时,如果某个field是分词的,那么es是不会给它建立doc value正排索引的,因为分词后,占用的空间过于大,所以默认是不支持分词field进行聚合。对于分词field,必须打开和使用fielddata,完全存在于纯内存中结构和doc value类似,如果是ngram或者是大量term,那么必将占用大量的内存,性能会变的很差。

如果一定要对分词的field执行聚合,那么必须将fielddata=true,然后es就会在执行聚合操作的时候,现场将field对应的数据,建立一份fielddata正排索引,fielddata正排索引的结构跟doc value是类似的,但是只会将fielddata正排索引加载到内存中来,然后基于内存中的fielddata正排索引执行分词field的聚合操作。这种方式会耗费大量的内存空间。

为什么fielddata必须在内存?因为分词的字符串,需要按照term进行聚合,需要执行更加复杂的算法和操作,如果基于磁盘和os cache,那么性能会很差。

54.string field聚合以及fielddata原理初探的更多相关文章

  1. SpringBoot-02 运行原理初探

    SpringBoot-02 运行原理初探 本篇文章根据b站狂神编写 pom.xml 2.1.父依赖 其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件! <parent> < ...

  2. mongodb 更新数组出现can't append to array using string field name

    数据库内容大概如下: { _id:, "hero_list" : { " : { , , "equip" : [ [ ], [ ], [ ], { , ...

  3. Python源代码剖析笔记3-Python运行原理初探

    Python源代码剖析笔记3-Python执行原理初探 本文简书地址:http://www.jianshu.com/p/03af86845c95 之前写了几篇源代码剖析笔记,然而慢慢觉得没有从一个宏观 ...

  4. String field contains invalid UTF-8 data when serializing a protocol buffer. Use the 'bytes' type if you intend to send raw bytes.

    [libprotobuf ERROR google/protobuf/wire_format.cc:1053] String field contains invalid UTF-8 data whe ...

  5. SHA-256算法和区块链原理初探

    组内技术分享的内容,目前网上相关资料很多,但读起来都不太合自己的习惯,于是自己整理并编写一篇简洁并便于(自己)理解和分享的文章. 因为之前对密码学没有专门研究,自己的体会或理解会特别标注为" ...

  6. 【Java基本功】一文读懂String及其包装类的实现原理

    String作为Java中最常用的引用类型,相对来说基本上都比较熟悉,无论在平时的编码过程中还是在笔试面试中,String都很受到青睐,然而,在使用String过程中,又有较多需要注意的细节之处. S ...

  7. Git 内部原理--初探 .git

    说到Git大家应该都非常熟悉,几乎每天都会用到它.在日常使用过程中,我们貌似并不需要关注其内部的原理,只需要记住那几个常用的命令,就可以说自己是会Git的人了.可是,事实真的是这样子的吗?今天我们就来 ...

  8. Spark核心原理初探

    一.运行架构概览 Spark架构是主从模型,分为两层,一层管理集群资源,另一层管理具体的作业,两层是解耦的.第一层可以使用yarn等实现. Master是管理者进程,Worker是被管理者进程,每个W ...

  9. 狂神说SpringBoot02:运行原理初探

    狂神说SpringBoot系列连载课程,通俗易懂,基于SpringBoot2.2.5版本,欢迎各位狂粉转发关注学习. 微信公众号:狂神说(首发)    Bilibili:狂神说Java(视频) 未经作 ...

随机推荐

  1. Patrik 音乐会的等待 单调栈的迷茫回忆

    STL 一定要学好 一定要学好,一定要学好!!! 题目链接:https://www.luogu.org/problemnew/show/P1823 我们需要单向查找:用单调栈: 思路:维护一个身高单调 ...

  2. clc和clear命令的使用

    clc命令是用来清除命令窗口的内容,这点不用多说.不管开启多少个应用程序,命令窗口只有一个,所以clc无论是在脚本m文件或者函数m文件调用时,clc命令都会清除命令窗口的内容.clear命令可以用来清 ...

  3. 关于Webpack的的认识及傻瓜式教学

    刚学习了Webpack,ememememememememem就赶脚是一个打包工具,将js.css.json.img等等通通打包为最终的文件,最后渲染为一个页面. 也是终于捋清了Webpack的思路,在 ...

  4. easyui-datebox 年月视图显示

    //年月视图做法 $('#startYearDate').datebox({ onShowPanel: function () { //显示日趋选择对象后再触发弹出月份层的事件,初始化时没有生成月份层 ...

  5. python自动化测试学习笔记-10YAML

    之前学习的编写测试用例的方法,都是从excel中编写接口的测试用例,然后通过读取excel文件进行接口自动化测试,这种方式我们叫做数据驱动的方式,由于excel操作起来不灵活,无法实现关联关系的接口测 ...

  6. 【js】callback时代的变更

    最近团队开始越来越多的使用es7标准的async/await,从最开始的promise到后面的generator,再到现在async,对于异步,每个时期都有着其特有的解决方案,今天笔者就以自己的接触为 ...

  7. C#命名空间 using的用法

    using的用法: 1. using指令:引入命名空间 这是最常见的用法,例如: using System; using Namespace1.SubNameSpace; 2. using stati ...

  8. Android 性能优化(16)线程优化:Creating a Manager for Multiple Threads 如何创建一个线程池管理类

    Creating a Manager for Multiple Threads 1.You should also read Processes and Threads The previous le ...

  9. vue中引入swiper插件

    这里我们使用npm的方式安装swiper插件. 1.npm install vue-awesome-swiper --save 2.在main.js文件中引入文件 import Vue from 'v ...

  10. 409 Longest Palindrome 最长回文串

    给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串.在构造过程中,请注意区分大小写.比如 "Aa" 不能当做一个回文字符串.注意:假设字符串的长度不会超过 ...