天天看點

白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理

白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理

概述

繼續跟中華石杉老師學習ES,第51篇

課程位址: https://www.roncoo.com/view/55

官網

fielddata: 戳這裡

白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理
白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理
白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理
白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理

示例

對于分詞的field執行aggregation,報錯

先構造下模拟索引及資料

PUT /artisan_index 
{
  "mappings": {
    "artisan_type": {
      "properties": {
        "artisan_filed": {
          "type": "text"
        }
      }
    }
  }
}




PUT /artisan_index/artisan_type/1
{
  "artisan_filed": "artisan_1"
}

PUT /artisan_index/artisan_type/2
{
  "artisan_filed": "artisan_2"
}           

複制

GET  /artisan_index/_mapping/artisan_type           

複制

白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理

我們建立的 artisan_filed是text類型,預設是分詞的,那麼我們對該字段進行 aggs看下

GET  /artisan_index/artisan_type/_search
{
  "size": 0,
  "aggs": {
    "group_by_artisan_field": {
      "terms": {
        "field": "artisan_filed"
      }
    }
  }
}           

複制

報錯如下:

{
        "type": "illegal_argument_exception",
        "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [artisan_filed] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
      }           

複制

白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理

對分詞的field,直接執行聚合操作,會報錯,大概意思是說,你必須要打開fielddata,然後将正排索引資料加載到記憶體中,才可以對分詞的field執行聚合操作,而且會消耗很大的記憶體 .

當然了,排序這種操作也是不行的。

白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理

給分詞的field,設定fielddata=true,可執行

#删除索引
DELETE artisan_index

#建立索引,設定text類型的字段的fielddata為true
PUT /artisan_index 
{
  "mappings": {
    "artisan_type": {
      "properties": {
        "artisan_filed": {
          "type": "text",
          "fielddata": true
        }
      }
    }
  }
}



#模拟資料
PUT /artisan_index/artisan_type/1
{
  "artisan_filed": "artisan_1"
}

PUT /artisan_index/artisan_type/2
{
  "artisan_filed": "artisan_2"
}


#檢視映射
GET  /artisan_index/_mapping/artisan_type



---------------           

複制

白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理
# 聚合操作
GET  /artisan_index/artisan_type/_search
{
  "size": 0,
  "aggs": {
    "group_by_artisan_field": {
      "terms": {
        "field": "artisan_filed"
      }
    }
  }
}           

複制

白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理

如果要對分詞的field執行聚合操作,必須将fielddata設定為true

使用field.keyword,對分詞的field進行聚合,可執行

#直接寫入資料,讓ES自動建立索引
PUT /artisan_index/artisan_type/1
{
  "artisan_filed": "artisan_1"
}

PUT /artisan_index/artisan_type/2
{
  "artisan_filed": "artisan_2"
}


#檢視映射
GET  /artisan_index/_mapping/artisan_type           

複制

白話Elasticsearch51-深入聚合資料分析之text field聚合以及fielddata原理概述官網示例分詞field+fielddata的工作原理
# artisan_filed.keyword  es内置的keyword也可以在沒設定fielddata=true的情況下聚合
GET  /artisan_index/artisan_type/_search
{
  "size": 0,
  "aggs": {
    "group_by_artisan_field": {
      "terms": {
        "field": "artisan_filed.keyword"
      }
    }
  }
}           

複制

artisan_filed.keyword es内置的keyword也可以在沒設定fielddata=true的情況下。

當然了,如果對不分詞的field執行聚合操作,直接就可以執行,不需要設定fieldata=true

分詞field+fielddata的工作原理

doc value --> 不分詞的所有field,可以執行聚合操作 --> 如果你的某個field不分詞,那麼在index-time,就會自動生成doc value --> 針對這些不分詞的field執行聚合操作的時候,自動就會用doc value來執行。

分詞field,是沒有doc value的。。。在index-time,如果某個field是分詞的,那麼是不會給它建立doc value正排索引的,因為分詞後,占用的空間過于大,是以預設是不支援分詞field進行聚合的

分詞field預設沒有doc value,是以直接對分詞field執行聚合操作,是會報錯的

對于分詞field,必須打開和使用fielddata,完全存在于純記憶體中。。。結構和doc value類似。。。如果是ngram或者是大量term,那麼必将占用大量的記憶體。。。

如果一定要對分詞的field執行聚合,那麼必須将fielddata=true,然後es就會在執行聚合操作的時候,現場将field對應的資料,建立一份fielddata正排索引,fielddata正排索引的結構跟doc value是類似的,但是隻會将fielddata正排索引加載到記憶體中來,然後基于記憶體中的fielddata正排索引執行分詞field的聚合操作

如果直接對分詞field執行聚合,報錯,提示讓我們開啟fielddata=true,告訴我們,會将fielddata uninverted index(正排索引),加載到記憶體,會耗費記憶體空間

為什麼fielddata必須在記憶體?分詞的字元串,需要按照term進行聚合,需要執行更加複雜的算法和操作,如果基于磁盤和os cache,那麼性能會很差