主要知识点:

  • 直接对分词的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. 25.EXTJS 主页面的jsp

    1. /** * @author sux * @time 2011-1-11 * @desc main page */ var mainPage = Ext.extend(Ext.Viewport,{ ...

  2. bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居【切比雪夫距离+并查集+multiset】

    参考:http://hzwer.com/4361.html 坐标开long long,inf开大点 先曼哈顿转切比雪夫(x+y,x-y),距离就变成了max(x',y'): 先按x排序,维护两个指针, ...

  3. bzoj 1627: [Usaco2007 Dec]穿越泥地【bfs】

    在洛谷上被卡了一个点开了O2才过= = bfs即可,为方便存储,把所有坐标+500 #include<iostream> #include<cstdio> #include&l ...

  4. 使用 script 的 module 属性实现 es6 以上的兼容

    几个月前看到了这篇文章 https://philipwalton.com/articles/deploying-es2015-code-in-production-today/,给了我很大的启发,本来 ...

  5. Windows 和 Linux 上Redis的安装守护进程配置

    # Windows 和 Linux 上Redis的安装守护进程配置 Redis 简介 ​ Redis是目前最常用的非关系型数据库(NOSql)之一,常以Key-Value的形式存储.Redis读写速度 ...

  6. 学习http协议的三次握手和四次挥手 ~~笔记

    http协议是基于tcp协议的  所以应该说是tcp协议的三次握手和四次挥手 SYN:请求建立连接,并在其序列号的字段进行序列号的初始值设定.建立连接,设置为1 FIN:用来释放一个连接.FIN=1表 ...

  7. android序列化(2)Parcelable与Parcel

    1.简介 Parcel  : 包裹 Android采用这个它封装消息数据.这个是通过IBinder通信的消息的载体.需要明确的是Parcel用来存放数据的是内存(RAM),而不是永久性介质(Nand等 ...

  8. 转 Shell调试篇

    检查语法 -n选项只做语法检查,而不执行脚本. sh -n script_name.sh 启动调试 sh -x script_name.sh 进入调试模式后,Shell依次执行读入的语句,产生的输出中 ...

  9. 全面学习ORACLE Scheduler特性(10)管理Chains

    5.2  管理Chains 5.2.1  修改Chains属性 基本上碰到修改CHAIN属性的机率不会太大,因此确实没啥可修改的,对于CHAIN对象来说,能够修改的属性只有两个:evaluation_ ...

  10. 小白的python之路 序

    计算机专科毕业,.net开发已有8年有余,中途断断续续,似懂非懂,积累了一些经验知识,但是不求甚解,属于那种一瓶不满半瓶子晃荡,这么一个状态. 主要从事web开发,涉及一些前端jq等,还有接口开发,搜 ...