Jason
Published on 2025-06-06 / 4 Visits
0
0

Elastic Search 索引及score

什么是索引(index)

三种索引

在es中,索引通常有3种意思

  1. 指一个保存数据的集合,类似传统数据库的表的概念。它是指用于区分不同的数据集,比如 /xdclass_shop。 这里xdclass_shop就是索引名。

  2. 保存文档到某个索引的动作,类似数据库insert/upate。最常见,也不用讨论。

  3. 指elasticsearch的倒排索引。

文档存储

在这里,我们讨论的是第一种,也就是数据集合。在 Elasticsearch 中,Index(索引) 是数据的逻辑容器,类似于传统数据库中的“表”(Table),用于存储、管理和查询具有相似结构的文档(Document)。它是 Elasticsearch 中最高层的数据组织单位,也是数据操作的核心入口。

index中一份document的样例

{
  "_index": "xdclass_shop",
  "_id": "TZ7zFZcBUQ0b6MKf1c_j",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "found": true,
  "_source": {
    "id": 123,
    "title": "小滴课堂架构大课",
    "pv": 244
  }
}

_index 文档所属索引名称。

_type 文档所属类型名。

_id Doc的主键。在写入的时候,可以指定该Doc的ID值,如果不指定,则系统自动生成一个唯一的UUID值。

_version 文档的版本信息。Elasticsearch通过使用version来保证对文档的变更能以正确的顺序执行,避免乱序造成的数据丢失。

seqno 严格递增的顺序号,每个文档一个,Shard级别严格递增,保证后写入的Doc的_seq_no大于先写入的Doc的_seq_no。

primary_term primary_term也和_seq_no一样是一个整数,每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term会递增1

found 查询的ID正确那么ture, 如果 Id 不正确,就查不到数据,found字段就是false。

_source 文档的原始JSON数据。

注意事项

合理设计 Index 结构:

避免过多的 Index(如按小时创建)导致集群元数据膨胀。

通过别名(Alias)隐藏 Index 细节,简化操作。

倒排索引

倒排索引是另外一种提到的“索引”, 它解决了从“文档包含什么词”到“词出现在哪些文档”这样传统的数据库的索引无法解决的问题。

想象一下你在查阅一本厚重的书后面的索引(Index)(不是Elasticsearch的Index,是传统书籍的索引)。这个索引通常是按字母顺序排列的关键词(Terms)列表,每个关键词后面跟着它出现的页码。

例如:

  • apple -> 5, 12, 45

  • banana -> 8, 22

  • elasticsearch -> 10, 15, 20, 33

这就是倒排索引的基本思想。 它把传统“正排”的关系(文档ID -> 文档内容)反转了,变成了词项(Term) -> 包含该词项的文档ID列表。

如何建立倒排索引

因为倒排索引涉及到分词等操作,所以是强语言相关的。这里只讨论英语情况下的步骤。其他语言如中文,在分词阶段有区别,别的阶段几乎一致

  1. 文档收集: 获取要索引的文档。

  2. 分词(Tokenization): 将每个文档的文本内容分割成一个个独立的词项(Tokens)。例如,“The quick brown fox jumps” -> ["the", "quick", "brown", "fox", "jumps"]。这一步是语言相关的。如果用英语分词器去分中文的词,就只能按字分了。

  3. 规范化(Normalization):
    - 小写化(Lowercasing): "The" -> "the"。
    - 去除停用词(Stop Words Removal): 移除常见但无实质意义的词(如 "the", "a", "an", "in")。
    - 词干还原(Stemming): 将单词还原为词根形式(如 "jumps", "jumped", "jumping" -> "jump")。
    -(可选)其他: 如处理同义词、转换字符编码等。

  4. 构建索引:
    遍历每个文档中规范化后的词项。对于每个词项:
    - 在词项词典中查找或创建该词项。
    - 在对应的倒排列表中添加或更新一个条目(记录该文档ID,增加TF计数,记录位置/偏移量等)。

倒排索引结构

在把文字切分成单词序列,之后记录下包含这些单词的文档,我们就获得了最简单的倒排索引。除此之外,还会加上词频信息。文档中的句子被划分为一个个term(term 用来表示一个单词或词语,取决于使用的分词方式),倒叙索引中存储着term,term的出现频率(tf,term frequency)和出现位置(倒叙索引中的单词是按顺序排列的,这张图没有体现出来),请注意这里的文档内容是document中的一个字段,也就是说每个被索引了的字段都有自己的倒叙索引。

优势

极快的全文搜索: 要找包含 apple 的所有文档可以直接查词典找到 apple,读取其倒排列表即可。速度远快于遍历所有文档。

高效的布尔查询:查询 apple AND banana可以分别获取 apple 和 banana 的倒排列表,求交集(找出同时包含两者的文档ID)。又或者 apple OR banana求并集,apple NOT banana求差集。

短语和邻近查询: 利用位置信息,可以精确查找连续出现的词组(如 "red apple")或词项之间距离在一定范围内的组合(如 elasticsearch NEAR/5 performance)。

相关性评分的基础: 这是倒排索引与评分关系最核心的部分。

什么是相关性评分

在 Elasticsearch(ES)中,相关性评分(Relevance Score)是一个非常重要的概念,它用于衡量文档与用户查询之间的匹配程度。它是 Elasticsearch 在搜索过程中为每个匹配的文档计算的一个数值,通常是一个浮点数(如 1.0、2.5 等)。这个数值越高,表示文档与查询的匹配程度越高,因此在搜索结果中排名越靠前。

相关性评分(Score)与倒排索引的关系

倒排索引是计算相关性得分的基石,因为它提供了评分算法所需的关键原始数据。

词频(TF - Term Frequency)

文档的倒排列表条目中存储了 TF(该词项在该文档中出现的次数)。一个词项在某个文档中出现的次数越多,通常认为该文档与该词项的相关性越高。 例如,文档A提到 elasticsearch 5次,文档B提到1次,在其他条件相似的情况下,文档A对于查询 elasticsearch 的得分会更高。评分公式通常会对TF进行某种标准化(如除以文档总词数),避免长文档天然占优。

逆文档频率(IDF - Inverse Document Frequency)

需要统计全局信息。通过倒排索引,可以很容易知道

  • doc_freq:包含某个词项的文档数量(即该词项倒排列表的长度)

  • total_docs:索引中文档的总数

一个词项在索引中出现的文档越少(越稀有),它的区分度越高,重要性越大。 例如,词项 the 几乎出现在所有文档中(IDF很低),它对区分文档没什么用。而词项 "倒排索引" 只在少数技术文档中出现(IDF很高),如果一个文档包含它,说明该文档很可能与技术搜索相关。IDF 的计算公式通常是 log(total_docs / (doc_freq + 1))。

字段长度归一化(Field-length Norm)

通常存储在倒排列表条目中或单独的存储结构中。惩罚长文档。 在长文档中,一个词项出现多次的“显著性”通常不如在短文档中出现相同次数。例如,词项 error 在1000词的文档中出现5次,和在50词的错误日志中出现5次,显然后者相关性更高。归一化因子通常基于字段的字符数或词项数。

词项权重(Term Boosting)

查询时指定(如 "title^2 quick fox" 表示 title 字段的 quickfox 重要性是其他字段的2倍)。它能提升特定词项或字段的重要性。

协调因子(Coordination)

查询时计算(基于倒排列表的交集结果)。奖励匹配了更多查询词项的文档。 例如查询 quick brown fox,匹配了所有三个词项的文档得分会比只匹配了 quick fox 的文档高。

倒排索引与 Score 的关系

  1. 数据基础: 倒排索引存储了计算相关性评分(Score)所需的核心原始数据

    • 词频(TF) -> 来自文档的倒排列表条目。

    • 逆文档频率(IDF) -> 需要统计整个倒排索引(词项的 doc_freqtotal_docs)。

    • 字段长度 -> 通常存储在倒排索引相关结构中。

  2. 查询执行: 当执行查询时,搜索引擎首先利用倒排索引快速定位到包含查询词项的所有文档(Doc ID 列表)。

  3. 评分计算: 对于这些候选文档,搜索引擎利用倒排索引中记录的 TFIDF、字段长度等信息,结合查询中指定的权重(Boost)和匹配的词项数量(协调因子),应用评分算法(如BM25) 为每个文档计算出一个 _score 值。

  4. 结果排序: 文档最终按照 _score 从高到低排序返回给用户,相关性最高的排在最前面。

简而言之:倒排索引是搜索引擎快速找到候选匹配文档的引擎,而存储在倒排索引中的词频、逆文档频率等信息,是计算这些文档与查询之间相关性得分(Score)的燃料。没有高效准确的倒排索引,就无法实现快速且按相关性排序的全文搜索。


Comment