大家都知道搜索搜引擎是什么,例如我们接触比较多的 百度、Google、必应、360搜索、淘宝搜索、京东搜索等等很多只要能搜索就可以被称为搜索引擎。以下是比较官方的说法。

搜索引擎(Search Engine)是根据一定的策略、运用特定的计算机程序去搜集信息,在对信息进行组织和处理后,为用户提供检索服务,将用户检索相关的信息展示给用户的一套系统。

搜索引擎的组成

搜索引擎一般由索引组件搜索组件所组成。

搜索引擎的工作原理

图解:

搜索引擎的工作顺序

索引组件:获取数据-->建立文档-->文档分析-->文档索引(倒排索引)
搜索组件:用户搜索接口-->建立查询(将用户键入的信息转换为可处理的查询对象)-->搜索查询-->展现结果

索引组件

注意:索引组件为上图中红色框部分
为什么索引组件的工作流程是由下往上呢?
举例:例如淘宝,当我们在淘宝中搜索一件商品的时候,在能搜索到的前提下,那它这个商品肯定是提前要存储到淘宝的存储库当中,淘宝卖家把一件衣服上架到了淘宝平台,这就叫做 Raw Content(原始内容);当衣服存储到淘宝的存储库当中呢,搜索引擎就开始获取这件衣服的图片信息和标题内容等,获取到的内容会被存为文档才能供搜索引擎使用,这个叫 Acquire Content获取内容;存为文档之后,一般来说,一句话或者一条信息都可以作为一个文档,但是现在需要建立文档 Build Document,建立文档的过程是向单个文档插入权重值,目的是为了在搜索引擎搜索的时候进行排序,当然是权值越高越容易被搜索到了哈,不然不会出现SEO的。文件建立成功后,搜索引擎还不能直接对文本进行索引呢,还需要将文档即文本内容分割成独立的元素,可以理解为切片、分词等,把一句话拆分成了好多个字或者说字节;切词过后,文档就要被加上索引列表啦,即我们搜索的时候,通过索引会给你搜索到1-10的数字、搜索2的时候会给你搜索到2-20的数字等,这就叫做添加索引 Idenx Document。这一系列统统被称为索引组件来完成的工作,接下来就等着被搜索引擎搜索吧。

淘宝的搜索框就是我们的用户搜索界面 Search User Interface,当我们在search interface输入东西去搜索内容的时候浏览器会把你输入的内容转换为HTML或Ajax的格式提交给搜索引擎服务器,即淘宝的搜索引擎服务器,由浏览换转换你输入内容的步骤叫做建立查询Build Query;当查询建立后,淘宝的搜索引擎就会拿着你输入的内容去存储库中寻找相匹配的内容,会直接查询上述步骤中已经建立好的索引,此步骤叫做搜索查询 Run Query;搜索到相匹配内容后,就要通过界面展现给你,淘宝的搜索引擎拿到数据后返回到你的浏览器当中,一次完整的搜索就此完成,此步骤叫做Render Results展现结果。

索引是一种数据结构,它允许对它存储在其中的单词进行快速随机访问。当需要从大量文本中快速检索文本目标时,必须首先将文本内容转换成能够进行快速搜索的格式,以建立针对文本的索引数据结构,此即为索引过程。

获取内容(Acquire Content)

由用户输入原始内容(Raw Content),然后由索引组件去获取内容(Acquire Content),是通过网络爬虫或其它方式来搜集需要索引的内容。Lucene并不提供任何获取内容的组件,因此,需要由其它应用程序负责完成这一项功能,例如入著名的开源爬虫程序Solr、Nutch、Grub及Aperture等。必要时还可以自行开发相关程序以高效获取自有的特定环境中的数据。获取到的内容需要剪切为小数据块,即文档(Document)。

建立文档(Build Document)

通过Acquire Centent获取的原始内容需要转换为专用部件(文档)才能供搜索引擎使用。
一般来说,一个网页、一个PDF文档、一封邮件或者一条日志信息都可以作为一个文档。文档由带“值(Value)”的"域(Field)"组成,例如标题(Title)、正文(body)、摘要(abstract)、作者(Author)和链接(url)等。不过,二进制格式的文档处理起来要麻烦一些,例如PDF文档。对于建立文档的过程来说有一个常见操作:向单个的文档和域中插入加权值,以便在搜索结果中对其进行排序。权值可在索引操作前静态生产,也可在搜索期间才动态生成。权值决定了其搜索相关度。

文档分析(Analyze Document)

搜索引擎不能直接对文本进行索引,确切地说,必须首先将文本分割成一系列被称为语汇单元(token)的独立原子元素,此过程即为文档分析。每个token大致能与自然语言中的“单词”对应起来,文档分析就是用于确定文档中的文本域如何分割成token序列。
此即为切词或分词。
文档分析中要解决的问题包括如何处理连接一体的各个单词、是否需要语法修正(例如原始内容存在错别字、是否需要向原始token中插入同义词)、是否需要将大写字符统一转换为小写字符,以及是否将单数和复数格式的单词合并成同一个token等。这通常需要词干分析器等来完成此类工作,Lucene提供了大量内嵌的分析器,也支持用户自定义分析器,甚至联合Lucene的token工具和过滤器创建自定义的分析链。

文档索引(Idenx Document)

在索引步骤中,文档将被加入到索引列表。事实上,Lucene为此仅提供了一个非常简单的API,而后自行内生地完成了此步骤的所有功能。

搜索组件

索引处理就是从索引中查找单词,从而找到包含该单词的文档的过程。搜索质量主要由查准率(Precision)和查全率两个指标进行衡量。
查准率用来衡量搜索系列过非相关文档的能力。
而查全率用来衡量搜索系统查找相关文档的能力。
另外,除了快速搜索大量文本和搜索速度之后,搜索过程还涉及到了许多其它问题,例如单项查询、多项查询、短语查询、通配符查询、结果ranking和排序,以及友好的查询输入方式等。这些问题的解决,通常需要多个组件协作完成。

用户搜索界面(Search User Interface)

UI(User Interface)是搜索引擎的重要组成部分,用户通过搜索引擎进行搜索交互时,他们会提交一个搜索请求,该请求需要先转换成合适的查询对象格式,以便搜索引擎能执行查询。

建立查询(Build Query)

用户提交的搜索请求通常以HTML表单或Ajax请求的形式由浏览器提交到搜索引擎服务器,因此,需要事先由查询解析器一类的组件将这个请求转换成搜索引擎使用的查询对象格式。

搜索查询(Run Query)

当查询请求建立完成后,就需要查询检索索引并返回与查询语句匹配的并根据请求排好序的文档。搜索查询组件有着复杂的工作机制,他们通常根据搜索理论模型执行查询操作。常见的搜索理论模型由纯布尔模型、向量空间模型及概率模型三种。Lucene采用了向空间模型和纯布尔模型。

展现结果(Render Results)

查询获得匹配查询语句并排好序的文档结构集后,需要用直观、经济的方式为用户展现结果。UI也需要为后续的搜索或者操作提供清晰的向导,如完善搜索结果、寻找与匹配结果相似的文档、进入下一页等。

但这是一套搜索引擎的流程,我们要通过什么实现呢?

图解ELK组件

下面来图解完成一套搜索引擎的应用组件

上图显示为Kibana组件来代替用户搜索接口(Search User Interface)功能,还要提供了一个Web界面供用户搜索。
上图显示为Elasticsearch组件来代替建立查询(Build Query)和搜索查询(Run Query)以及把搜索结果返回给用户接口的展现结果(Render Results)功能。
上图显示为Lucene组件来代替文档索引(Index Document)和文档分析(Analyze Document)的功能。
上图显示为Logstash组件来代替原始内容(Raw Content)和获取内容(Acquire Content)及构建文档(Build Document)的功能。

Elastic Stack

其中Elasticsearch和Logstash及Kibana这三款组件都是Elastic公司旗下的产品
Elastic Stack:
Elasticsearch
Logstash/Beats
Kibana
这三款工具本来是被称为ELK的后来被更名为Elastic Stack,为什么会出现这种情况呢?
因为Logstash被用来作为日志的抽取工具实在是弱爆了,性能非常差,硬件资源消耗大,因为Logstash使用JRuby所研发,我们知道Python使用C语言所研发,Ruby也是使用C语言所编写,而JRuby却是用Java所研发,Java本来就很慢,而还用Java写Ruby成为了JRuby,那更是慢上加慢,Ruby这样的动态语言比较适合做Web网站的快速开发,但是像日志采集的后端应用,需要负责日志的采集和解析,尤其像解析日志会很耗CPU资源的,这样大的日志数据量更容易碰天花板。
所以后来就有人用GoLang重写了一款工具叫Beats,Beats被称为轻量型数据采集器。Beats平台集合了多种单一用途的数据采集器,他们从成百上千或成千上万台机器和系统向Logstash或Elasticsearch发送数据。
为什么有了Beast还要向Logstash发送数据呢?为什么不直接取代Logstash呢?
因为Beast虽然好用,也很强大,但Logstash的一部分功能Beast还是不具备的。所以还会依然会用到Logstash。

ES的核心组件
物理组件:
        集群:
            集群状态:green, yellow, red
        节点:
        Shard:

    Lucene的核心组件:
        索引(index):数据库
        类型(type):表
        文档(Document):行
        映射(Mapping):

    域选项:来控制Lucene将文档添加进域索引后对该域执行的操作:
        Index.ANALYZED:切词和分析;
        Index.NOT_ANALYZED:做索引,但不做分析;
        Index.NO:不做索引;

Lucene是Apache旗下的一款非常出色的项目,提供基于Java的索引和搜索技术,以及拼写检查,命中突出显示和高级分析/标记化功能。