ES
Basic
什么是倒排索引
倒排索引是一种用于快速查找文档中单词出现位置的数据结构。
它是搜索引擎中最核心的数据结构之一,与传统的"文档→单词"正向索引相反,倒排索引是"单词→文档"的映射关系。
正向索引 vs 倒排索引
- 正向索引:文档ID → 文档内容(单词列表)
 - 倒排索引:单词 → 文档ID列表(包含该单词的所有文档)
 
假设我们有3个文档:
- 文档1:"Python is a programming language"
 - 文档2:"Python is named after Monty Python"
 - 文档3:"Programming is fun"
 
构建的倒排索引:
{
    "python": [1, 2],
    "is": [1, 2, 3],
    "a": [1],
    "programming": [1, 3],
    "language": [1],
    "named": [2],
    "after": [2],
    "monty": [2],
    "fun": [3]
}Python实现倒排索引
import re
from collections import defaultdict
 
def build_inverted_index(documents):
    """
    构建倒排索引
    
    参数:
        documents: 文档列表,每个文档是一个字符串
        
    返回:
        倒排索引字典 {词: [包含该词的文档ID列表]}
    """
    inverted_index = defaultdict(list)
    
    for doc_id, doc in enumerate(documents, start=1):
        # 使用正则表达式分割单词,并转为小写
        words = re.findall(r'\w+', doc.lower())
        
        for word in set(words):  # 使用set去重,避免同一文档多次记录
            inverted_index[word].append(doc_id)
            
    return inverted_index
 
def search(inverted_index, query):
    """
    使用倒排索引搜索
    
    参数:
        inverted_index: 倒排索引字典
        query: 查询字符串
        
    返回:
        包含查询词的文档ID列表
    """
    words = re.findall(r'\w+', query.lower())
    if not words:
        return []
    
    # 获取第一个词的文档列表
    result = set(inverted_index.get(words[0], []))
    
    # 与其他词的文档列表取交集
    for word in words[1:]:
        result.intersection_update(inverted_index.get(word, []))
    
    return sorted(result)
 
# 示例文档
documents = [
    "Python is a programming language",
    "Python is named after Monty Python",
    "Programming is fun"
]
 
# 构建倒排索引
inverted_index = build_inverted_index(documents)
print("倒排索引:")
for word, doc_ids in sorted(inverted_index.items()):
    print(f"{word}: {doc_ids}")
 
# 搜索示例
queries = ["Python", "programming", "Python programming", "monty python", "fun is"]
print("\n搜索结果:")
for query in queries:
    print(f"'{query}': {search(inverted_index, query)}")
 输出:
倒排索引:
a: [1]
after: [2]
fun: [3]
is: [1, 2, 3]
language: [1]
monty: [2]
named: [2]
programming: [1, 3]
python: [1, 2]
 
搜索结果:
'Python': [1, 2]
'programming': [1, 3]
'Python programming': [1]
'monty python': [2]
'fun is': [3]场景:
- 词频(Term Frequency):单词在文档中出现的次数
 - 位置信息:单词在文档中出现的位置(用于短语查询)
 - 权重信息:如TF-IDF值
 
对比:
| 索引类型 | 适用场景 | 倒排索引优势 | 
|---|---|---|
| B+树(MySQL) | 精确匹配(如WHERE id=123) | 无法高效支持模糊搜索 | 
| 哈希索引 | 等值查询(如Redis的K-V) | 不支持范围或部分匹配 | 
| 向量索引 | 语义搜索(如“类似图片”) | 需倒排索引补充关键词过滤 | 

