文章十:ElasticSearch索引字段高级属性

Fielddata字段

text类型的数据天生就是用于全文检索的,可分词的特性使他失去了唯一性的特征,所以如果想让es对于text字段进行聚合和统计的话,可以使用fielddata属性。

复制代码
PUT index_test
{
  "mappings": {
    "_source": {
      "enabled": true
    },
    "properties": {
      "name": {
        "type": "text",
        "fielddata":true
      },
      "age": {
        "type": "integer"
      }
    }
  },
  "settings": {
    "number_of_replicas": 0
  }
}

设置为true之后就可以对于text类型的数据进行聚合统计了。但是这个是再内存中创建一个类似于doc_value的结构,很影响性能。

Elasticsearch eager_global_ordinals 字段属性详解


一、核心概念

eager_global_ordinals 是 Elasticsearch 中用于 keyword/text 类型字段 的映射参数,核心作用是控制全局序数(global ordinals)的构建时机,本质是「聚合性能优化开关」。

1. 先搞懂:什么是 global ordinals(全局序数)?

ES 中每个索引段(segment)会为字段的唯一词条生成本地序数(term → 整数 ID),但聚合 / 排序需要跨段统一映射,因此 ES 会生成全局序数

  • 它是一个「全分片唯一的词条→整数 ID」映射表,基于 doc_values(keyword 默认开启)构建;
  • 作用:让聚合 / 排序直接用整数 ID 运算,大幅提升性能(避免重复解析字符串);
  • 支持字段:仅 keyword(默认支持)、开启 fielddatatext 字段(不推荐)。

2. eager_global_ordinals 的核心逻辑

表格

取值 构建时机 核心影响
false(默认) 懒加载:首次执行聚合 / 排序时,临时构建全局序数 索引刷新快,但首次聚合延迟高(高基数字段尤其明显)
true 预加载:在索引刷新(refresh)/ 段合并时,提前构建全局序数 索引刷新耗时增加、内存占用上升,但聚合查询延迟大幅降低

简单来说:把「聚合时的计算成本」提前到「索引写入阶段」,用写入性能换查询性能。


二、底层原理与关键特性

1. 为什么需要它?

  • 默认懒加载:高基数字段(如用户 ID、商品 ID,唯一值多)首次聚合时,构建全局序数需要遍历全部分片的所有段,耗时极长(秒级甚至分钟级);
  • 开启预加载:在 refresh 阶段(默认 1 秒一次)提前完成计算,用户查询时直接用缓存好的序数,聚合延迟从秒级降到毫秒级。

2. 关键限制

  • 仅支持 keyword 类型 (text 需开启 fielddata,但 fielddata 会占用大量堆内存,生产环境严禁使用);
  • 仅对依赖全局序数的操作生效:terms 聚合、histogram 聚合、字段排序等;
  • 映射修改后仅对新写入 / 刷新的分片生效,历史数据需重新索引。

三、实战配置示例

1. 创建索引时配置

json

复制代码
PUT /index_product
{
  "mappings": {
    "properties": {
      "product_name": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "eager_global_ordinals": true,  // 对keyword子字段开启预加载
            "ignore_above": 256
          }
        }
      },
      "user_id": {
        "type": "keyword",
        "eager_global_ordinals": true  // 高基数keyword字段,开启预加载优化聚合
      }
    }
  }
}

2. 动态修改已有索引的映射

json

复制代码
PUT /index_product/_mapping
{
  "properties": {
    "user_id": {
      "type": "keyword",
      "eager_global_ordinals": true
    }
  }
}

四、适用场景与避坑指南

✅ 推荐开启的场景

  1. 高基数字段:如用户 ID、商品 ID、订单号等唯一值多的 keyword 字段,且高频做聚合 / 排序;
  2. 查询优先的业务:如实时报表、数据分析系统,要求聚合响应快,可接受索引写入延迟略增;
  3. 分片稳定的索引:索引写入频率适中,refresh 耗时增加在可接受范围内。

❌ 不推荐开启的场景

  1. 低基数字段:如性别、状态、分类等唯一值少的字段,懒加载耗时极低,开启预加载无收益;
  2. 写入优先的业务:如日志、埋点数据,写入 QPS 极高,refresh 耗时增加会严重影响写入性能;
  3. 超大基数字段:如 UUID、长字符串,预加载会占用大量堆内存,甚至引发 OOM。

analyzer设置:

分词规则配置项,分别控制「索引写入」「普通搜索」「短语搜索」三个阶段的分词逻辑,下面逐个拆解核心知识点:


1. analyzer

核心定义

指定 ** 文档写入 / 更新(索引阶段)** 使用的分词器,决定原始文本如何被拆分为词条,存入倒排索引。

关键知识点

  • 生效时机:仅在文档写入 / 更新时生效,直接决定倒排索引的词条结构,是全文检索的基础。
  • 配置示例"analyzer": "standard" 表示使用 ES 内置的 standard 分词器(默认分词器),规则为:按空格 / 标点拆分、自动转小写、不过滤停用词(默认),适配通用英文 / 混合文本场景。
  • 核心影响:索引分词规则决定了「能搜到什么」,如果索引时拆分的词条和搜索词不匹配,就会出现搜不到的情况。

2. search_analyzer

核心定义

指定 ** 普通全文搜索(如 match/multi_match 查询)** 时,对用户输入的搜索词使用的分词器。

关键知识点

  • 生效时机:仅在执行普通全文查询时生效,只处理搜索词,不修改已存储的倒排索引。
  • 配置示例"search_analyzer": "stop" 表示使用 stop 分词器,在 standard 基础上额外过滤英文停用词(如 the/a/is 等无意义虚词),避免停用词干扰搜索结果。
  • 核心作用 :优化搜索精准度,比如用户搜索 the quick fox,会自动过滤 the,只匹配 quickfox 相关的文档。
  • 默认规则 :如果不配置 search_analyzer,默认复用 analyzer 的分词规则。

3. search_quote_analyzer

核心定义

指定 ** 短语匹配查询(如 match_phrase/ 带引号的精确短语搜索)** 时,对搜索词使用的分词器。

关键知识点

  • 生效时机:仅在执行短语匹配类查询时生效,专门处理「精确短语」场景的搜索词。
  • 配置示例"search_quote_analyzer": "stop" 表示短语搜索时也用 stop 分词器,过滤停用词。
  • 核心价值 :解决短语搜索的停用词问题。比如用户搜索 "the quick brown fox",如果不配置该属性,默认会完整匹配包含 the quick brown fox 的短语;配置后会自动过滤 the,只匹配 "quick brown fox",避免因停用词导致短语匹配失败。
  • 默认规则 :如果不配置,默认复用 search_analyzer 的分词规则。

三个属性的核心区别总结

表格

属性 生效阶段 核心用途 典型配置逻辑
analyzer 文档写入(索引) 构建倒排索引的分词规则 standard 保留完整词条,保证召回率
search_analyzer 普通全文搜索 处理普通搜索词的分词规则 stop 过滤停用词,提升精准度
search_quote_analyzer 短语匹配搜索 处理短语搜索词的分词规则

📌 Elasticsearch similarity 字段属性详解


一、核心定义

similarity 是 Elasticsearch 中所有可被搜索的字段类型text/keyword/ 数值 / 日期等)的映射属性,用于指定文档评分(相关性计算)使用的算法模型,决定了 ES 如何判断「一个文档和用户搜索词的匹配程度」,直接影响搜索结果的排序。


二、核心作用

当你执行全文搜索(如 match 查询)时,ES 会为每个匹配的文档计算一个 _score(相关性分数),分数越高,排序越靠前。similarity 就是控制这个分数计算逻辑的核心开关。


三、ES 内置的 3 种核心相似度算法

1. BM25(默认值,绝大多数场景推荐)

  • 全称:Okapi BM25,是当前信息检索领域的工业级标准算法。
  • 核心逻辑
    • 基于词频(TF)、逆文档频率(IDF)、字段长度归一化(Field Length Normalization)计算分数;
    • 对长文本做惩罚(长字段中出现关键词的权重更低),避免长文档天然高分;
    • 自带词频饱和(Term Frequency Saturation):关键词出现超过一定次数后,分数不再线性增长,避免关键词堆砌作弊。
  • 适用场景:通用全文搜索、电商商品搜索、日志检索等绝大多数业务场景。

2. classic(兼容旧版,不推荐生产使用)

  • 对应算法:Lucene 经典的 TF/IDF 算法(ES 5.x 之前的默认算法)。
  • 核心逻辑
    • 基础公式:score = TF * IDF * boost * fieldNorm
    • 词频越高分数越高(无饱和限制,易被关键词堆砌作弊);
    • 字段长度归一化:短字段权重高于长字段。
  • 适用场景:仅用于兼容旧版 ES 索引,新业务不推荐使用。

3. BM25F(多字段加权扩展,特殊场景使用)

  • 全称:BM25 Field,是 BM25 的多字段加权版本。
  • 核心逻辑:支持为不同字段设置独立权重(如标题字段权重 10,内容字段权重 1),在多字段搜索时更精准控制评分。
  • 适用场景:需要手动调整不同字段评分权重的多字段搜索场景(如「标题匹配优先于内容匹配」)。

四、实战配置示例

1. 基础配置(指定字段使用 BM25 算法)

json

复制代码
PUT /index_demo
{
  "mappings": {
    "properties": {
      "content": {
        "type": "text",
        "similarity": "BM25"  // 显式指定使用BM25(默认可省略)
      },
      "title": {
        "type": "text",
        "similarity": "BM25F"  // 多字段加权场景使用BM25F
      }
    }
  }
}
相关推荐
就叫飞六吧2 小时前
Tomcat /hvm类加载机制
java·笔记
共享家95272 小时前
Java入门( 日期类与 BigDecimal 工具类 )
java·开发语言
冯RI375II694872 小时前
食品FDA认证:确保食品周边产品安全的标准
大数据
好好学习叭~2 小时前
正则表达式
java·开发语言
草莓熊Lotso2 小时前
MySQL 内置函数指南:日期、字符串、数学函数实战
android·java·linux·运维·数据库·c++·mysql
计算机学姐2 小时前
基于SpringBoot的蛋糕烘焙销售服务系统
java·spring boot·后端·spring·tomcat·intellij-idea·mybatis
hongtianzai2 小时前
Go vs Java:终极性能对决
java·开发语言·golang
程序员老乔2 小时前
Java 新纪元 — JDK 25 + Spring Boot 4 全栈实战(四):结构化并发 & 作用域值,订单聚合查询的新写法
java·数据库·spring boot
汤姆yu2 小时前
基于python大数据的天气可视化及预测系统
大数据·开发语言·python