毫秒级ElasticSearch搜索背后的倒排索引技术

什么是倒排索引?

倒排索引(Inverted Index)是Elasticsearch中一种重要的索引技术,它将文档中text/keyword类型字段的每个词都映射到包含该词的文档列表。这种索引结构使得在大规模文本数据中进行快速的全文搜索成为可能。

ElasticSearch为什么使用倒排索引?

想象一下,当你需要找到一本书中特定关键词的位置时,传统的方式是一页一页地翻阅,这无疑是非常耗时且低效的。然而,如果这本书的每个单词后面都有一个“索引页码”告诉你哪些页面出现了这个关键词,那么你就能瞬间找到目标位置。

倒排索引为每个关键词都创建了一个对应的索引列表,记录了哪些文档包含了该关键词。

这个索引不仅能够告诉你文档的名称或位置,还能精确地指出关键词在文档中出现的频率和文档的权重或其他标签,这些信息使其能够更加智能地排列搜索结果。 不仅极大地提高了搜索引擎的搜索速度,也提高了搜索的准确性

便于理解, 下面我们使用简单的例子,用python实现倒排索引技术

python实现倒排索引技术

首先导入需要的库:

import jieba

这里的jieba用于中文文本分词, ElasticSearch 在构建索引导入文档数据时, 分词插件会将文档中的text/keyword字段进行分词构建倒排索引.

假设我们有以下四个文档需要导入索引中

documents = [
    "Elasticsearch是一个分布式的、基于RESTful的搜索和分析引擎。",
    "它建立在Apache Lucene之上。",
    "Elasticsearch是用Java开发的。",
    "它提供了一个分布式、支持多租户的全文搜索引擎。"
]

我们先为文档创建倒排索引,这里我们遍历所有的文档,为每个文档进行分词, 构建词与文档之间的映射关系. 分词阶段我们选用 jieba.lcut_for_search(doc)为文档进行分词可以获取更好的搜索效果.并使用自定义的停用词对分词进行过滤.

# 创建倒排索引
inverted_index = {}

for doc_id, doc in enumerate(documents):
    stopwords = [" ", ",", "、", "。", "了", "在", "和", "是", "它", "的", "之", "用"]
    # 使用jieba分词对文档进行分词
    words = [word for word in jieba.lcut_for_search(doc) if word not in stopwords]

    # 遍历每个词
    for word in words:
        # 如果词不在倒排索引中,则创建一个空列表
        if word not in inverted_index:
            inverted_index[word] = []

        # 将文档ID添加到词的倒排索引列表中
        inverted_index[word].append(doc_id)

# 打印倒排索引
print("| 词 | 文档ID列表 |")
print("|----|------------|")
for word, doc_ids in inverted_index.items():
    print(f"| {word} | {doc_ids} |")

倒排索引构建结果:

在这里插入图片描述

实现全文搜索功能:

这里我们使用 jieba.lcut(query) 对搜索词进行分词, 在文档中查找包含搜索词的所有文档:

# 定义一个函数,用于根据词搜索文档ID
def search_docs(query):
    # 使用jieba分词对查询词进行分词
    stopwords = [" ", ",", "、", "。", "了", "在", "和", "是", "它", "的", "之", "用"]
    # 使用jieba分词对文档进行分词
    query_words = [word for word in jieba.lcut(query) if word not in stopwords]

    # 初始化结果列表
    result = []

    # 遍历查询词的每个词
    for word in query_words:
        # 如果词在倒排索引中,则将对应的文档ID添加到结果列表中
        if word in inverted_index:
            result.extend(inverted_index[word])

    # 返回结果列表(去重)
    return list(set(result))

搜索包含"Elasticsearch搜索"的文档ID:

query = "Elasticsearch 搜索"
result = search_docs(query)
target_docs = [documents[doc_id] for doc_id in result]

print(f"包含'{query}'的文档ID:{result},\n文档为:\n{target_docs}")

搜索结果如下:

包含'Elasticsearch 搜索'的文档ID:
[0, 2, 3],
文档内容为:
['Elasticsearch是一个分布式的、基于RESTful的搜索和分析引擎。',
'Elasticsearch是用Java开发的。',
'它提供了一个分布式、支持多租户的全文搜索引擎。']

总结

倒排索引是Elasticsearch中的一种重要索引技术,它将文档中的每个词映射到包含该词的文档列表,实现了快速全文搜索, 在信息爆炸时代为搜索引擎提供了强有力的支持,让我们更轻松地找到所需信息。

赶快来关注我,一起从零开始学习ElasticSearch搜索

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值