Skip to content

倒排索引与分词

倒排索引

正排 vs 倒排

正排索引:
┌─────┬──────────────┐
│ ID  │  Document   │
├─────┼──────────────┤
│ 1  │ 我爱中国     │
│ 2  │ 中国有多长   │
│ 3  │ 中国加油     │
└─────┴──────────────┘

倒排索引:
┌─────┬────────────┐
│Term │  Postings  │
├─────┼────────────┤
│ 我  │   [1]      │
│ 爱  │   [1]      │
│ 中国│ [1,2,3]    │
│ 有  │   [2]      │
│ 多长│   [2]      │
│ 加油│   [3]      │
└─────┴────────────┘

ES中的倒排索引结构

java
// Lucene TermIndex
{
  "term": "中国",
  "docFreq": 3,           // 出现在多少文档
  "totalTermFreq": 4,     // 出现总次数
  "postingList": [
    {docId: 1, positions: [1]},  // 位置信息
    {docId: 2, positions: [0]},
    {docId: 3, positions: [0]}
  ]
}

组成结构

组成部分说明
Term Dictionaryterms按字典序排序
Term Indexterms的FST索引,加速定位
Posting List每个term对应的文档列表
Positionterm在文档中的位置
Frequencyterm在文档中出现次数

分词器

分词流程

原始文本 → Character Filter → Tokenizer → Token Filter → Tokens

                           多个过滤器链式处理

内置分词器

分词器说明示例
standard默认,Unicode分词"I love China" → [i, love, china]
whitespace空格分词"I love China" → [i, love, china]
simple字母分词,非字母分割"I love-China" → [i, love, china]
keyword不分词,返回原文本"I love China" → [i love china]
pattern正则分词按正则表达式
stop移除停用词移除the、a等

中文分词器

分词器说明
IK业界最常用,支持ik_smart/ik_max_word
jiebaPython结巴的Java版本
hanlp哈工大出品,学术背景强
ansj清华nlg实验室
json
// IK配置
{
  "settings": {
    "analysis": {
      "analyzer": {
        "ik_analyzer": {
          "type": "custom",
          "tokenizer": "ik_max_word"
        }
      }
    }
  }
}

自定义分词器

json
PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "char_filter": ["html_strip"],
          "tokenizer": "standard",
          "filter": ["lowercase", "stop", "porter_stem"]
        }
      }
    }
  }
}

面试考点

Q: 为什么倒排索引搜索快?

  • term直接定位,无需全表扫描
  • 只扫包含查询词的文档
  • FST索引加速term定位

Q: 分词器选择考虑什么?

  • 语言:中文/英文
  • 场景:搜索/索引
  • 性能:精确度vs速度

Q: 停用词怎么配置?

json
{
  "settings": {
    "analysis": {
      "filter": {
        "my_stop": {
          "type": "stop",
          "stopwords": ["the", "a", "an"]
        }
      }
    }
  }
}

最后更新: