ES(Elasticsearch)是一个基于Lucene的分布式开源搜索引擎,它采用了倒排索引(Inverted Index)来实现全文检索。倒排索引是一种索引方式,它将每个词语与包含该词语的所有文档进行关联。
什么是倒排索引?
正向索引(Forward Index)是将文档中的每个单词与其出现的位置进行记录。例如,对于以下文本:
The quick brown fox jumped over the lazy dog
正向索引可能会存储为:
the : [1]
quick : [2]
brown : [3]
fox : [4]
jumped : [5]
over : [6]
lazy : [7]
dog : [8]
而倒排索引则是将每个单词作为索引键,将包含该单词的文档作为索引值进行记录。例如,对于以上文本,倒排索引可能会存储为:
the : [1]
quick : [2]
brown : [3]
fox : [4]
jumped : [5]
over : [6]
lazy : [7]
dog : [8]
可以看到,倒排索引的键是词语,而值是包含该词语的文档编号(或者其他包含文档信息的数据结构)。这样做的好处是,可以快速找到包含某个词语的文档列表,从而实现全文检索。
ES中的倒排索引
在ES中,每个索引都拥有一个或多个分片(Shard),每个分片都是一个独立的倒排索引。当向ES中添加文档时,它会将文档进行分词,将每个词语与该文档的ID进行关联,最终存储到对应的倒排索引分片中。例如,考虑以下文档:
{
"id": 1,
"title": "The quick brown fox jumped over the lazy dog",
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed dignissim volutpat nunc eget venenatis."
}
当这个文档被添加到名为my_index的索引中时,ES会将其分词,生成如下关系:
the : [1]
quick : [1]
brown : [1]
fox : [1]
jumped : [1]
over : [1]
lazy : [1]
dog : [1]
Lorem : [1]
ipsum : [1]
dolor : [1]
sit : [1]
amet : [1]
consectetur : [1]
adipiscing : [1]
elit : [1]
Sed : [1]
dignissim : [1]
volutpat : [1]
nunc : [1]
eget : [1]
venenatis : [1]
可以看到,ES将每个词语与文档ID进行了关联。这样,当我们需要搜索包含某个词语的文档时,ES只需要查找包含该词语的文档列表即可。如果需要查找包含多个词语的文档,则可以将它们的文档列表取交集(AND)或并集(OR)。
示例代码
以下是使用Python语言访问ES中倒排索引的示例代码:
from elasticsearch import Elasticsearch
# 连接到本地ES节点
es = Elasticsearch()
# 搜索包含"fox"和"dog"的文档
result = es.search(index="my_index", body={
"query": {
"bool": {
"must": [
{ "match": { "title": "fox" } },
{ "match": { "title": "dog" } }
]
}
}
})
# 输出搜索结果
print(result["hits"]["hits"])
此代码会搜索名为my_index的索引中,找到包含“fox”和“dog”两个词语的所有文档。其中,bool查询表示需要同时满足两个条件(即AND操作),而match查询可以自动将搜索关键字进行分词,从而实现全文检索。
ES倒排索引原理是实现全文检索的重要基础,在ES中通过倒排索引可以快速查找包含某个词语的文档列表,从而实现高效的搜索功能。在使用ES时,需要了解倒排索引的工作原理,并合理地设计文档结构和索引属性,以充分利用它的检索能力。