这篇文章是摘自其他人写的,百度百科上的解释好笼统,我只用过mysql这种关系型数据库,抽象的概念理解起来很难,这篇文建的解释还是很形象的,所以摘取了部分。
关于搜索引擎
各位知道,搜索程序一般由索引链及搜索组件组成。
索引链功能的实现需要按照几个独立的步骤依次完成:检索原始内容、根据原始内容来创建对应的文档、对创建的文档进行索引。
搜索组件用于接收用户的查询请求并返回相应结果,一般由用户接口、构建可编程查询语句的方法、查询语句执行引擎及结果展示组件组成。
著名的开源程序Lucene是为索引组件,它提供了搜索程序的核心索引和搜索模块,例如图中的“Index”及下面的部分;而ElasticSearch则更像一款搜索组件,它利用Lucene进行文档索引,并向用户提供搜索组件,例如“Index”上面的部分。二者结合起来组成了一个完整的搜索引擎。
索引组件
索引是一种数据结构,它允许对存储在其中的单词进行快速随机访问。
当需要从大量文本中快速检索文本目标时,必须首先将文本内容转换成能够进行快速搜索的格式,以建立针对文本的索引数据结构,此即为索引过程。
它通常由逻辑上互不相关的几个步骤组成
第一步:获取内容。
过网络爬虫或蜘蛛程序等来搜集及界定需要索引的内容。
Lucene并不提供任何获取内容的组件,因此,需要由其它应用程序负责完成这一功能,例如著名的开源爬虫程序Solr、Nutch、Grub及Aperture等。
必要时,还可以自行开发相关程序以高效获取自有的特定环境中的数据。获取到的内容需要建立为小数据块,即文档(Document)。
第二步:建立文档。
获取的原始内容需要转换成专用部件(文档)才能供搜索引擎使用。
一般来说,一个网页、一个PDF文档、一封邮件或一条日志信息可以作为一个文档。文档由带“值(Value)”的“域(Field)”组成,例如标题(Title)、正文(body)、摘要(abstract)、作者(Author)和链接(url)等。
不过,二进制格式的文档处理起来要麻烦一些,例如PDF文件。
对于建立文档的过程来说有一个常见操作:向单个的文档和域中插入加权值,以便在搜索结果中对其进行排序。权值可在索引操作前静态生成,也可在搜索期间才动态生成。权值决定了其搜索相关度。
第三步:文档分析。
搜索引擎不能直接对文本进行索引,确切地说,必须首先将文本分割成一系列被称为语汇单元(token)的独立原子元素,此过程即为文档分析。
每个token大致能与自然语言中的“单词”对应起来,文档分析就是用于确定文档中的文本域如何分割成token序列。
文档分析中要解决的问题包括如何处理连接一体的各个单词、是否需要语法修正(例如原始内容存在错别字)、是否需要向原始token中插入同义词(例如laptop和notebook)、是否需要将大写字符统一转换为小写字符,以及是否将单数和复数格式的单词合并成同一个token等。
这通常需要词干分析器等来完成此类工作,Lucene提供了大量内嵌的分析器,也支持用户自定义分析器,甚至联合Lucene的token工具和过滤器创建自定义的分析链。
第四步、文档索引
在索引步骤中,文档将被加入到索引列表。事实上,Lucene为此仅提供了一个非常简单的API,而后自行内生地完成了此步骤的所有功能。
搜索组件
索引处理就是从索引中查找单词,从而找到包含该单词的文档的过程。搜索质量主要由查准率(Precision)和查全率(Recall)两个指标进行衡量。
查准率用来衡量搜索系列过滤非相关文档的能力,而查全率用来衡量搜索系统查找相关文档的能力。
另外,除了快速搜索大量文本和搜索速度之后,搜索过程还涉及到了许多其它问题,例如单项查询、多项查询、短语查询、通配符查询、结果ranking和排序,以及友好的查询输入方式等。这些问题的解决,通常需要多个组件协作完成。
搜索组件主要由以下几个部分组成:
1、用户搜索界面
UI(User Interface)是搜索引擎的重要组成部分,用户通过搜索引擎界面进行搜索交互时,他们会提交一个搜索请求,该请求需要先转换成合适的查询对象格式,以便搜索引擎能执行查询。
2、建立查询
用户提交的搜索请求通常以HTML表单或Ajax请求的形式由浏览器提交到搜索引擎服务器,因此,需要事先由查询解析器一类的组件将这个请求转换成搜索引擎使用的查询对象格式。
3、搜索查询
当查询请求建立完成后,就需要查询检索索引并返回与查询语句匹配的并根据请求排好序的文档。
搜索查询组件有着复杂的工作机制,它们通常根据搜索理论模型执行查询操作。
常见的搜索理论模型有纯布尔模型、向量空间模型及概率模型三种。Lucene采用了向量空间模型和纯布尔模型。
4、展现结果
查询获得匹配查询语句并排好序的文档结果集后,需要用直观、经济的方式为用户展现结果。
UI也需要为后续的搜索或操作提供清晰的向导,如完善搜索结果、寻找与匹配结果相似的文档、进入下一页面等。
本节的最后简单说一下Lucene。
Lucene是一款高性能的、可扩展的信息检索(IR)工具库,是由Java语言开发的成熟、自由开源的搜索类库,基于Apache协议授权。
Lucene只是一个软件类库,如果要发挥Lucene的功能,还需要开发一个调用Lucene类库的应用程序。
文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,而域的值则是真正被搜索的内容。每个域都有其标识名称,通常为一个文本值或二进制值。
将文档加入索引中时,需要首先将数据转换成Lucene能识别的文档和域,域值是被搜索的对象。
例如,用户输入搜索内容“title:elasticsearch”时,则表示搜索“标题”域值中包含单词“elasticsearch”的所有文档。
默认情况下,所有文档都没有加权值,或者说其加权因子都为1.0。
通过改变文档的加权因子,可以指示Lucene在计算相关性时或多或少地考虑到该文档针对索引中其它文档的重要程度,从而能够将有着较大加权因子的文档排列在较前的位置。
除了对文档进行加权,Lucene还支持对域进行加权操作。
ElasticSearch(简称ES)是一个基于Lucene构建的开源、分布式、RESTful的全文本搜索引擎。
不过,ElasticSearch却也不仅只是一个全文本搜索引擎,它还是一个分布式实时文档存储,其中每个field均是被索引的数据且可被搜索;也是一个带实时分析功能的分布式搜索引擎,并且能够扩展至数以百计的服务器存储及处理PB级的数据。
如前所述,ElasticSearch在底层利用Lucene完成其索引功能,因此其许多基本概念源于Lucene。
ES的基本概念。
索引(Index)
ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。
索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新及删除操作。一个ES集群中可以按需创建任意数目的索引。
类型(Type)
类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。
例如,在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。
文档(Document)
文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。
文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。
映射(Mapping)
ES中,所有的文档在存储之前都要首先进行分析。用户可根据需要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本需要进行额外处理等等。
另外,ES还提供了额外功能,例如将域中的内容按需排序。事实上,ES也能自动根据其值确定域的类型。
接下去再说说ES Cluster相关的一些概念。
集群(Cluster)
ES集群是一个或多个节点的集合,它们共同存储了整个数据集,并提供了联合索引以及可跨所有节点的搜索能力。
多节点组成的集群拥有冗余能力,它可以在一个或几个节点出现故障时保证服务的整体可用性。
集群靠其独有的名称进行标识,默认名称为“elasticsearch”。节点靠其集群名称来决定加入哪个ES集群,一个节点只能属一个集群。
如果不考虑冗余能力等特性,仅有一个节点的ES集群一样可以实现所有的存储及搜索功能。
节点(Node)
运行了单个实例的ES主机称为节点,它是集群的一个成员,可以存储数据、参与集群索引及搜索操作。
类似于集群,节点靠其名称进行标识,默认为启动时自动生成的随机Marvel字符名称。
用户可以按需要自定义任何希望使用的名称,但出于管理的目的,此名称应该尽可能有较好的识别性。
节点通过为其配置的ES集群名称确定其所要加入的集群。
分片(Shard)和副本(Replica)
ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它通过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每一个物理的Lucene索引称为一个分片(shard)。
每个分片其内部都是一个全功能且独立的索引,因此可由集群中的任何主机存储。创建索引时,用户可指定其分片的数量,默认数量为5个。
Shard有两种类型:primary和replica,即主shard及副本shard。
Primary shard用于文档存储,每个新的索引会自动创建5个Primary shard,当然此数量可在索引创建之前通过配置自行定义,不过,一旦创建完成,其Primary shard的数量将不可更改。
Replica shard是Primary Shard的副本,用于冗余数据及提高搜索性能。
每个Primary shard默认配置了一个Replica shard,但也可以配置多个,且其数量可动态更改。ES会根据需要自动增加或减少这些Replica shard的数量。
ES集群可由多个节点组成,各Shard分布式地存储于这些节点上。
ES可自动在节点间按需要移动shard,例如增加节点或节点故障时。简而言之,分片实现了集群的分布式存储,而副本实现了其分布式处理及冗余功能。