全文搜索之 Elasticsearch

转载 2015年11月20日 22:58:33

 全文搜索之 Elasticsearch  

概述

Elasticsearch (ES)是一个基于 Lucene 的开源搜索引擎,它不但稳定、可靠、快速,而且也具有良好的水平扩展能力,是专门为分布式环境设计的。

特性

  • 安装方便:没有其他依赖,下载后安装非常方便;只用修改几个参数就可以搭建起来一个集群
  • JSON:输入/输出格式为 JSON,意味着不需要定义 Schema,快捷方便
  • RESTful:基本所有操作(索引、查询、甚至是配置)都可以通过 HTTP 接口进行
  • 分布式:节点对外表现对等(每个节点都可以用来做入口);加入节点自动均衡
  • 多租户:可根据不同的用途分索引;可以同时操作多个索引

集群

其中一个节点就是一个 ES 进程,多个节点组成一个集群。一般每个节点都运行在不同的操作系统上,配置好集群相关参数后 ES 会自动组成集群(节点发现方式也可以配置)。集群内部通过 ES 的选主算法选出主节点(目前版本 1.2 存在脑裂问题),而集群外部则是可以通过任何节点进行操作,无主从节点之分(对外表现对等/去中心化,有利于客户端编程,例如故障重连)。

索引

“索引”有两个意思:

  • 作为动词,它指的是把一个文档“保存”到 ES 中的过程,索引一个文档后,我们就可以使用 ES 搜索到这个文档
  • 作为名词,它是指保存文档的地方,相当于一个数据库概念中的“库”

为了方便理解,我们可以将 ES 中的一些概念对应到我们熟悉的关系型数据库上:

    ES         索引         类型         文档    
    DB         库          表     行

分片

ES 是一个分布式系统,我们一开始就应该以集群的方式来使用它。它保存索引时会选择适合的“分片”(Primary Shard),把索引保存到其中(我们可以把分片理解为一块物理存储区域)。分片的分法是固定的,而且是安装时候就必须要决定好的(默认是 5),后面就不能改变了。

既然有主分片,那肯定是有“从”分片的,在 ES 里称之为“副本分片”(Replica Shard)。副本分片主要有两个作用:

  • 高可用:某分片节点挂了的话可走其他副本分片节点,节点恢复后上面的分片数据可通过其他节点恢复
  • 负载均衡:ES 会自动根据负载情况控制搜索路由,副本分片可以将负载均摊

一个示例

来个示例总结一下上面的内容(结合下面的图一起看):

  • 3 个 ES 节点(es-58/59/60)组成一个集群
  • 搭建集群时使用默认的主分片数 5,shard0~shard4
  • 该集群内有加入两个索引 index1、index2
  • 这两个索引中分别“索引”(保存)了两个文档
  • index1 索引中这个文档被 ES 自动保存到了分片 2 中,主分片在 es-58 节点,副本分片在 es-59 节点
  • index2 索引中这个文档被 ES 自动保存到了分片 2 中,主分片在 es-59 节点,副本分片在 es-58 节点

shards

(该图是使用 ES 的 RESTful 接口获取的,后面会介绍常用接口)

多租户

ES 的多租户简单的说就是通过多索引机制同时提供给多种业务使用,每种业务使用一个索引(关于多租户的详细定义与用途,可以参考这里)。前面我们提到过可以把索引理解为关系型数据库里的库,那多索引可以理解为一个数据库系统建立多个库给不同的业务使用。

在实际使用时,我们可以通过每个租户一个索引的方式将他们的数据进行隔离,并且每个索引是可以单独配置参数的(可对特定租户进行调优),这在典型的多租户场景下非常有用:例如我们的一个多租户应用需要提供搜索支持,这时可以通过 ES 根据租户建立索引,这样每个租户就可以在自己的索引下搜索相关内容了。

RESTful

这个特性非常方便,最关键的是 ES 的 HTTP 接口不只是可以进行业务操作(索引/搜索),还可以进行配置,甚至是关闭 ES 集群。下面我们介绍几个很常用的接口:

  •  /_cat/nodes?v:查集群状态
  • /_cat/shards?v:查看分片状态
  • /${index}/${type}/_search:搜索

v 是 verbose 的意思,这样可以更可读(有表头,有对齐),_cat 是监测相关的 APIs,/_cat?help 来获取所有接口。${index} 和 ${type} 分别是具体的某一索引某一类型,是分层次的。我们也可以直接在所有索引所有类型上进行搜索:/_search。

官方术语表

最后,来份官方的术语表翻译,巩固一下理解:

analysis 分析

分析是将文本(text)转化为查询词(term)的过程。使用不同的分析器,这三种短语:FOO BAR,Foo-Bar,foo,bar 都有可能被分解成查询词 foo 与 bar。这些查询词实际上将被存储在索引中。一次对 FoO:bAR 的全文查询(不是查询词查询)可能会被分析为为查询词 foo,bar,可以匹配上保存在索引中的查询词。这就是分析处理过程(包含了索引与搜索),它使得 es 可以进行全文查询。

cluster 集群

一个或多个拥有同一个集群名称的节点组成了一个集群。每个集群都会自动选出一个主节点,如果该主节点故障,则集群会自动选出新的主节点来替换故障节点。

document 文档

一个文档就是一个保存在 es 中的 JSON 文本,可以把它理解为关系型数据库表中的一行。每个文档都是保存在索引中的,拥有一种类型和 id。一个文档是一个 JSON 对象(一些语言中的 hash / hashmap / associative array)包含了 0 或多个字段(键值对)。原始的 JSON 文本在索引后将被保存在 _source 字段里,搜索完成后返回值中默认是包含该字段的。

id

Id 是用于标识文档的,一个文档的索引/类型/id 必须是唯一的。文档 id 是自动生成的(如果不指定)。

field 字段

一个文档包含了若干字段,或称之为键值对。字段的值可以是简单(标量)值(例如字符串、整型、日期),也可以是嵌套结构,例如数组或对象。一个字段类似于关系型数据库表中的一列。每个字段的映射都有一个字段类型(不要和文档类型搞混了),它描述了这个字段可以保存的值类型,例如整型、字符串、对象。映射还可以让我们定义一个字段的值如何进行分析。

index 索引

一个索引类似关系型数据库中的一个数据库,它可以映射为多种类型。一个索引就是逻辑上的一个命名空间,对应到 1 或多个主分片上,可以拥有 0 个或多个副本分片。

mapping 映射

一个映射类似于关系型数据库中的模式定义。每个索引都存在一个映射,它定义了该索引中的每一种类型,以及索引相关的配置。映射可以显示定义,或者在文档被索引时自动创建。

node 节点

一个节点是集群中的一个 es 运行实例。测试时,多个节点可以同时启在同一个服务器上,生产环境一般是一个服务器上一个节点。节点启动时将使用单播(或者是组播)来发现和自己配置的集群名称相同的集群,并尝试加入到该集群中。

primary shard 主分片

每个文档都会被保存在一个主分片上。当我们索引一个文档时,它将在一个主分片上进行索引,然后才放到该主分片的各副本分片上。默认情况下,一个索引有 5 个主分片。我们可以指定更少或更多的主分片来伸缩索引可处理的文档数。需要注意的是,一旦索引创建,就不能修改主分片个数。

replica shard 副本分片

每个主分片可以拥有 0 个或多个副本分片。一个副本分片是主分片的一份拷贝,这样做有两个主要原因:

  1. 故障转移:当主分片失效时,一个副本分片会被提升为主分片
  2. 提高性能:获取与搜索请求可以被主分片或副本分片处理。默认情况下,每个主分片都有一个副本分片,副本分片的数量可以动态调整。在同一个节点上,副本分片和其主分片不会同时运行

routing 路由

当我们索引一个文档时,它将被保存在一个主分片上,分片的选择是通过路由值哈希得到的。默认情况下,路由值来自于文档 id,如果该文档指定来了父文档,则路由值来自于父文档 id(这是为了确保子文档和父文档被保存在相同的分片上)。该值可以在索引时指定,也可以通过映射路由字段来指定。

shard 分片

一个分片就是一个 Lucene 实例,它是 es 管理的底层“工作单元”。一个索引是逻辑上的一个命名空间,指向主分片和副本分片。索引的主分片和副本分片数量必须明确指定好,在应用代码使用时只需要处理和索引的交互,不会涉及到和分片的交互。Elasticsearch 会在集群中的所有节点上设置好分片,但节点失效或加入新节点时会自动将移动节点分片。

source field 源字段

默认情况下,在获取和搜索请求返回值中的 _source 字段保存了源 JSON 文本,这使得我们可以直接在返回结果中访问源数据,而不需要根据 id 再发一次检索请求。注意:索引的 JSON 字符串将完整返回,无论是否是一个合法的 JSON。该字段的内容也不会描述数据如何被索引。

term 查询词

一个查询词是一个被 es 索引的确切值。查询词 foo,Foo,FOO 是不同的。查询词可以使用查询词查询接口进行获取。

text 文本

文本(或称之为全文)是普通的、非结构化的文本,例如本段话。默认情况下,文本将被分析为查询词,查询词将被保存在索引中。为能够进行全文搜索,文本字段在索引时将被分析为查询词,查询关键字在搜索时也将被分析为查询词,通过对比查询词是否相同而完成全文搜索。

type 类型

一种类型类似于关系型数据库中的一张表。每种类型都有若干字段,可以用于指定给该类型文档。映射定义了该文档中的每个字段如何进行分析。

参考

Elasticsearch全文检索

简介  Elasticsearch是一个实时分布式搜索和分析引擎,用于全文搜索、结构化搜索、分析以及将这三者混合使用。Elasticsearch实现全文索引,需要使用分词器,默认使用的standard...
  • yanggd1987
  • yanggd1987
  • 2016年03月24日 09:24
  • 852

elasticsearch的实现全文检索

 转自:http://zhaoyanblog.com/archives/495.html            elasticsearch一个准实时的搜索引擎,基于lucene构建,它...
  • wilsonke
  • wilsonke
  • 2015年06月03日 08:43
  • 3491

Elasticsearch配合mysql实现全文搜索(一) 安装Elasticsearch

需要下载的东西 Elasticsearch: https://www.elastic.co/products/elasticsearch 我目前用的是6.1.3最新版本 Log...
  • ITfooter
  • ITfooter
  • 2018年02月03日 09:51
  • 27

[Elasticsearch] 全文搜索

[Elasticsearch] 全文搜索 (一) - 基础概念和match查询 现在我们已经讨论了搜索结构化数据的一些简单用例,是时候开始探索全文搜索了 - 如何在全文字段中搜索来找到最相关的文档...
  • wang_zhenwei
  • wang_zhenwei
  • 2015年12月22日 10:00
  • 854

ElasticSearch核心基础之搜索

一 搜索方式 我们知道搜索有2种方式:一种是通过URL参数搜索,另一种是通过POST请求参数进行搜索 1.1 通过URL参数搜索 比如GET http://hadoop-all-01:920...
  • zhanglh046
  • zhanglh046
  • 2017年11月14日 11:38
  • 706

elasticsearch全文搜索

全文搜索查询类型基于词项查询 term 或 fuzzy 这样的底层查询,对单个词项进行操作,不需要分析阶段;term 查询只对倒排索引的词项精确匹配,不会对词的多样性进行处理(如, foo 或 FOO...
  • Ricky110
  • Ricky110
  • 2017年12月24日 15:21
  • 22

Elasticsearch全文检索企业开发记录总结(二):ES客户端搭建

项目依赖 org.elasticsearch.client transport 5.4.0 org.ap
  • ll_mor
  • ll_mor
  • 2017年12月25日 15:08
  • 113

MongoDB数据自动同步到ElasticSearch(实现中文全文检索)

问题-方案1.产品需要全文检索,数据库是使用的MongoDB,MongoDB的全文检索太慢,打算使用ElasticSearch2.方案1:利用 ElasticSearch 的 River 来同步数据,...
  • MyHerux
  • MyHerux
  • 2016年02月25日 11:35
  • 2405

Elasticsearch全文检索系统实现深入详解

题记学习ES的童鞋,都有一个开发一个类似百度的搜索引擎的想法。当然功能不一定是百度、360、谷歌传统的搜索引擎那么强大。但是,能实现基本的全文检索、指定类型的检索、评分高低优先级排序等等。那么问题来了...
  • wojiushiwo987
  • wojiushiwo987
  • 2017年07月23日 17:05
  • 2758

Elasticsearch全文搜索的解决方案,走了不少弯路

在对Elasticsearch进行全文搜索时,走了不少弯路。其实最终发现就一点点设置要的问题。 1.注意在mapping里面将_all enabled 示例: { "template":...
  • xiaohelong2005
  • xiaohelong2005
  • 2014年11月26日 15:18
  • 1851
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:全文搜索之 Elasticsearch
举报原因:
原因补充:

(最多只允许输入30个字)