【Elastic Engineering】Elasticsearch:fielddata 介绍

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch:fielddata 介绍

作者:刘晓国


默认情况下,大多数字段都已编入索引,这使它们可搜索。 但是,脚本中的排序,聚合和访问字段值需要与搜索不同的访问模式。


搜索需要回答“哪个文档包含该术语?”这个问题,而排序和汇总则需要回答一个不同的问题:“此字段对该文档的值是什么?”。


大多数字段可以将索引时生产的磁盘 doc_values 用于此数据访问模式,但是文本(text)字段不支持 doc_values。


替代的方案,文本(text)字段使用查询时内存中的数据结构,称为 fielddata。 当我们首次将该字段用于聚合,排序或在脚本中使用时,将按需构建此数据结构。 它是通过从磁盘读取每个段的整个反向索引,反转术语↔︎文档关系并将结果存储在 JVM 堆中的内存中来构建的。


Fielddata 针对 text 字段在默认时是禁用的


Fielddata 会占用大量堆空间,尤其是在加载大量的文本字段时。 一旦将字段数据加载到堆中,它在该段的生命周期内将一直保留在那里。 同样,加载字段数据是一个昂贵的过程,可能导致用户遇到延迟的情况。 这就是默认情况下禁用字段数据的原因。


假如我们创建一个如下的myindex的索引:

PUT myindex
{
  "mappings": {
    "properties": {
      "address": {
        "type": "text"
      }
    }
  }
}
PUT myindex/_doc/1
{
  "address": "New York"  
}

如果您尝试对文本字段中的脚本进行排序,汇总或访问值:

GET myindex/_search
{
  "size": 20,
  "aggs": {
    "aggr_mame": {
      "terms": {
        "field": "address",
        "size": 5
      }
    }
  }
}

则会看到以下异常:

image.png

显然,我们不能对 text 字段进行聚合处理。那么我们该如何处理这个问题呢?


我们的一种方法就是在配置 mapping 的时候加入"fielddata"=true 这个选项。我们来重新对我们的 myindex 的 mapping 进行配置:

DELETE myindex
PUT myindex
{
  "mappings": {
    "properties": {
      "address": {
        "type": "text",
        "fielddata": true
      }
    }
  }
}
PUT myindex/_doc/1
{
  "address": "New York"  
}
GET myindex/_search
{
  "size": 0,
  "aggs": {
    "aggr_mame": {
      "terms": {
        "field": "address",
        "size": 5
      }
    }
  }
}

在这里,我们尽管还是把 address 这个字段设置为 text,但是由于我们加入了 "fielddata"=true,那么我们,我们就可以对这个项进行统计了。

image.png

与简单的搜索操作不同,排序和聚合需要能够发现在特定文档的特定字段中可以找到哪些术语。 对于这些任务和其他任务,必须具有与Elasticsearchimage.png(反向)索引相反的数据结构。 这就是 fielddata 的目的。


细心的开发者,如果这个时候去 Kibana 创建一个以 myindex 为索引的 index pattern,我们可以发现:

image.png

我们的 address 字段变为 aggregatable,也就是说我们可以对它进行做聚合分析尽管它没有 doc_values。


在启动fielddata之前


在启用 fielddata 之前,请考虑为什么将文本字段用于聚合,排序或在脚本中使用。 这样做通常没有任何意义。


在索引之前会分析文本字段,以便可以通过搜索 new 或 york 来找到类似 New York 的值。 当您可能想要一个名为 New York 的存储桶时,此字段上的术语汇总将返回一个叫做 new 存储桶和一个叫做 york 存储桶。


相反,你应该有一个用于全文搜索的文本字段,以及一个为聚合启用 doc_values 的未分析的 keyword 字段,如下所示:

DELETE myindex
PUT myindex
{
  "mappings": {
    "properties": {
      "address": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

这样,我们可以使用 address 来做全文的搜索,而 address.keyword 被用来做 aggregations, sorting 及在脚本中使用。


参考:


【1】https://www.elastic.co/guide/en/elasticsearch/reference/current/fielddata.html


【2】https://qbox.io/blog/field-data-elasticsearch-cluster-instability


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
JSON 数据格式 索引
【Elastic Engineering】Elasticsearch:Elasticsearch 中的数据强制匹配
Elasticsearch:Elasticsearch 中的数据强制匹配
147 0
【Elastic Engineering】Elasticsearch:Elasticsearch 中的数据强制匹配
|
数据库 索引
|
存储 运维 监控
|
SQL 自然语言处理 数据可视化
|
存储 缓存 API
|
JSON JavaScript 前端开发
|
存储 索引
|
存储 API 索引
|
Web App开发 存储 人工智能
|
固态存储 搜索推荐 Java
【Elastic Engineering】Elasticsearch:如何提高 Elasticsearch 数据摄入速度
Elasticsearch:如何提高 Elasticsearch 数据摄入速度
376 1
【Elastic Engineering】Elasticsearch:如何提高 Elasticsearch 数据摄入速度