python系列之搜索引擎原理与开发流程(Elasticsearch)

风流意气都作罢 提交于 2019-12-05 13:16:09

Elasticsearch


简介与原理

You know, for search!

文档 https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html

Elasticsearch是一个基于Lucene库的搜索引擎

它提供了一个分布式、支持多用户的全文搜索引擎,具有HTTP Web接口和无模式JSON文档。所有其他语言可以使用 RESTful API 通过端口 9200 和 Elasticsearch 进行通信

Elasticsearch是用Java开发的,并在Apache许可证下作为开源软件发布。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。

根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。

Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。

Elasticsearch是分布式的,这意味着索引可以被分成分片,每个分片可以有0个或多个副本。每个节点托管一个或多个分片,并充当协调器将操作委托给正确的分片。再平衡和路由是自动完成的。相关数据通常存储在同一个索引中,该索引由一个或多个主分片和零个或多个复制分片组成。一旦创建了索引,就不能更改主分片的数量。

Elasticsearch 是一个实时的分布式搜索分析引擎,它被用作全文检索、结构化搜索、分析以及这三个功能的组合

  • Wikipedia 使用 Elasticsearch 提供带有高亮片段的全文搜索,还有 search-as-you-type 和 did-you-mean 的建议。
  • 卫报 使用 Elasticsearch 将网络社交数据结合到访客日志中,实时的给它的编辑们提供公众对于新文章的反馈。
  • Stack Overflow 将地理位置查询融入全文检索中去,并且使用 more-like-this 接口去查找相关的问题与答案。
  • GitHub 使用 Elasticsearch 对1300亿行代码进行查询。

Lucene 仅仅只是一个库,然而,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确的形容:

  • 一个分布式的实时文档存储,每个字段 可以被索引与搜索

  • 一个分布式实时分析搜索引擎

  • 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据

属于面向文档的数据库
Elasticsearch 是 面向文档 的,意味着它存储整个对象或 文档。Elasticsearch 不仅存储文档,而且 索引每个文档的内容使之可以被检索。在 Elasticsearch 中,你 对文档进行索引、检索、排序和过滤–而不是对行列数据。

Elasticsearch 有2.x、5.x、6.x 三个大版本,不向下兼容。


搜索的原理

Elasticsearch 本质是数据库,那么关系型数据库为什么不用来做检索引擎?

  • 关系数据库查询的缺点

    • 关键词检索

      # 全文检索"python"  范围: 文章标题 和 文章内容
      select * from t_article where title like "%python%" or content like "%python%" 
      
    • 即使title和content字段建立了索引, 也不能完美使用索引, 只对"python%"的查询才会使用索引, 慢查询效率极低

Elasticsearch 搜索的原理

  • 分析
  • 建立倒排索引
  • 相关性排序

假设我们有两个文档,每个文档的 content 域包含如下内容:

1.The quick brown fox jumped over the , lazy+ dog
2.Quick brown foxes leap over lazy dogs in summer

  • 分析

    • 对于关键词进行提取和优化
    • 1分词
      • 将搜索内容以词条形式拆分
    • 2标准化
      • 忽略大小写
        • :Quick 和 quick 以独立的词条(token)出现,然而用户可能认为它们是相同的词。
        • Quick 可以小写化为 quick 。
      • 忽略单复数
        • :fox 和 foxes 非常相似, 就像 dog 和 dogs ;他们有相同的词根。
        • foxes 可以 词干提取 --变为词根的格式-- 为 fox 。类似的, dogs 可以为提取为 dog 。
      • 同义词合并
        • :jumped 和 leap, 尽管没有相同的词根,但他们的意思很相近。他们是同义词。
        • jumped 和 leap 是同义词,可以索引为相同的单词 jump 。
    • 3处理停用词
      • 谓词, 语气词, 主语
        -像the ,in等就会被忽略不建立词条

    正向排列好以后是这样(实际不是这样)
    在这里插入图片描述
    如果你想检索含有某个词条的文档你就得遍历所有的文档,否则你不能结束,这时候就要看倒排索引 ,在此之前介绍下相关名词.

对于查询的字符串必须与词条(token)进行相同的标准化处理,才能保证搜索的正确性。

分词和标准化的过程称为 分析 (analysis) :

  • 首先,将一块文本分成适合于倒排索引的独立的 词条 , -> 分词

  • 之后,将这些词条统一化为标准格式以提高它们的“可搜索性” -> 标准化
    分析工作是由分析器 完成的: analyzer

  • 字符过滤器

首先,字符串按顺序通过每个 字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将 & 转化成 and。

  • 分词器

其次,字符串被 分词器 分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条。

  • Token 过滤器 (词条过滤器)

最后,词条按顺序通过每个 token 过滤器 。这个过程可能会改变词条(例如,小写化 Quick ),删除词条(例如, 像 a, and, the 等无用词),或者增加词条(例如,像 jump 和 leap 这种同义词)。

  • 倒排/反向索引
    倒排索引(英语:Inverted index),也常被称为反向索引、置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。它是文档检索系统中最常用的数据结构
# 反向索引
Term      Doc_1  Doc_2
-------------------------
Quick   |       |  X
The     |   X   |
brown   |   X   |  X
dog     |   X   |
dogs    |       |  X
fox     |   X   |
foxes   |       |  X
in      |       |  X
jumped  |   X   |
lazy    |   X   |  X
leap    |       |  X
over    |   X   |  X
quick   |   X   |
summer  |       |  X
the     |   X   |
------------------------

如果我们想搜索 quick brown ,我们只需要查找包含每个词条的文档:

Term      Doc_1  Doc_2
-------------------------
brown   |   X   |  X
quick   |   X   |
------------------------
Total   |   2   |  1

两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单 相似性算法 ,那么,我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。

  • 相关性排序

默认情况下,搜索结果是按照 相关性 进行倒序排序的——最相关的文档排在最前。

相关性可以用相关性评分表示,评分越高,相关性越高。

评分的计算方式取决于查询类型 不同的查询语句用于不同的目的: fuzzy 查询(模糊查询)会计算与关键词的拼写相似程度,terms 查询(词组查询)会计算 找到的内容与关键词组成部分匹配的百分比,但是通常我们说的 相关性 是我们用来计算全文本字段的值相对于全文本检索词相似程度的算法。

Elasticsearch 的相似度算法 被定义为检索词频率/反向文档频率, TF/IDF ,包括以下内容:

  • 检索词频率

检索词在该字段出现的频率?出现频率越高,相关性也越高。 字段中出现过 5 次要比只出现过 1 次的相关性高。

  • 反向文档频率

每个检索词在索引中出现的频率?频率越高,相关性越低。检索词出现在多数文档中会比出现在少数文档中的权重更低。

  • 字段长度准则

字段的长度是多少?长度越长,相关性越低。 检索词出现在一个短的 title 要比同样的词出现在一个长的 content 字段权重更大。


  • 开发搜索引擎流程

    • 爬虫 :数据采集
    • 分布式存储
    • 分析
    • 建立倒排索引
    • 相关性排序

Elasticsearch在web项目中的应用

  • 检索引擎
  • 纠错提醒
  • 自动补全
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!