多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
Elasticsearch 使用一种称为倒排索引的结构,它适用于快速的全文搜索。 <br/> 见其名,知其意,有倒排索引,肯定会对应有正向索引。正向索引(forward index),反向索引(inverted index)更熟悉的名字是倒排索引。 <br/> 所谓的正向索引,就是搜索引擎会将待搜索的文件都对应一个文件 ID,搜索时将这个ID 和搜索关键字进行对应,形成 K-V 对,然后对关键字进行统计计数。 :-: ![](https://img.kancloud.cn/7a/b9/7ab99107fb8cd103d1a6936a0d898cbb_534x242.png) 正向索引 但是互联网上收录在搜索引擎中的文档的数目是个天文数字,这样的索引结构根本无法满足实时返回排名结果的要求。所以,搜索引擎会将正向索引重新构建为倒排索引,即把文件ID对应到关键词的映射转换为关键词到文件ID的映射,每个关键词都对应着一系列的文件,这些文件中都出现这个关键词。 :-: ![](https://img.kancloud.cn/fc/32/fc32ecc42263d1501574dd41295841b4_529x262.png) 倒排索引 一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表。例如,假设我们有两个文档,每个文档的 content 域包含如下内容: * The quick brown fox jumped over the lazy dog * Quick brown foxes leap over lazy dogs in summer 为了创建倒排索引,我们首先将每个文档的 content 域拆分成单独的 词(我们称它为 词条或 tokens ),创建一个包含所有不重复词条的排序列表,然后列出每个词条出现在哪个文档。结果如下所示: :-: ![](https://img.kancloud.cn/93/05/9305b000d87c538a4e60d5c5877f2201_218x369.png) 现在,如果我们想搜索 quick、brown ,我们只需要查找包含每个词条的文档: :-: ![](https://img.kancloud.cn/52/3a/523a9de4eb90d9b8553fa7b3f04e9d8e_302x191.png) 两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单相似性算法,那么我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。 <br/> 但是,我们目前的倒排索引有一些问题: * Quick 和 quick 以独立的词条出现,然而用户可能认为它们是相同的词。 * fox 和 foxes 非常相似, 就像 dog 和 dogs ;他们有相同的词根。 * jumped 和 leap, 尽管没有相同的词根,但他们的意思很相近。他们是同义词。 使用前面的索引搜索 +Quick +fox 不会得到任何匹配文档。(记住,+ 前缀表明这个词必须存在。)只有同时出现 Quick 和 fox 的文档才满足这个查询条件,但是第一个文档包含quick fox ,第二个文档包含 Quick foxes 。 <br/> 我们的用户可以合理的期望两个文档与查询匹配。我们可以做的更好。 <br/> 如果我们将词条规范为标准模式,那么我们可以找到与用户搜索的词条不完全一致,但具有足够相关性的文档。例如: * Quick 可以小写化为 quick 。 * foxes 可以 词干提取 --变为词根的格式-- 为 fox 。类似的, dogs 可以为提取为 dog 。 * jumped 和 leap 是同义词,可以索引为相同的单词 jump 。 现在索引看上去像这样: :-: ![](https://img.kancloud.cn/c5/7f/c57fb8bee97e4200f95dc7dd4efa065d_277x350.png) 这还远远不够。我们搜索 +Quick +fox 仍然 会失败,因为在我们的索引中,已经没有 Quick 了。但是,如果我们对搜索的字符串使用与 content 域相同的标准化规则,会变成查询+quick +fox,这样两个文档都会匹配!分词和标准化的过程称为**分析**。这非常重要。你只能搜索在索引中出现的词条,所以索引文本和查询字符串必须标准化为相同的格式。