全文搜索之 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 节点
(该图是使用 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 个或多个副本分片。一个副本分片是主分片的一份拷贝,这样做有两个主要原因:
- 故障转移:当主分片失效时,一个副本分片会被提升为主分片
- 提高性能:获取与搜索请求可以被主分片或副本分片处理。默认情况下,每个主分片都有一个副本分片,副本分片的数量可以动态调整。在同一个节点上,副本分片和其主分片不会同时运行
routing 路由
当我们索引一个文档时,它将被保存在一个主分片上,分片的选择是通过路由值哈希得到的。默认情况下,路由值来自于文档 id,如果该文档指定来了父文档,则路由值来自于父文档 id(这是为了确保子文档和父文档被保存在相同的分片上)。该值可以在索引时指定,也可以通过映射路由字段来指定。
shard 分片
一个分片就是一个 Lucene 实例,它是 es 管理的底层“工作单元”。一个索引是逻辑上的一个命名空间,指向主分片和副本分片。索引的主分片和副本分片数量必须明确指定好,在应用代码使用时只需要处理和索引的交互,不会涉及到和分片的交互。Elasticsearch 会在集群中的所有节点上设置好分片,但节点失效或加入新节点时会自动将移动节点分片。
source field 源字段
默认情况下,在获取和搜索请求返回值中的 _source 字段保存了源 JSON 文本,这使得我们可以直接在返回结果中访问源数据,而不需要根据 id 再发一次检索请求。注意:索引的 JSON 字符串将完整返回,无论是否是一个合法的 JSON。该字段的内容也不会描述数据如何被索引。
term 查询词
一个查询词是一个被 es 索引的确切值。查询词 foo,Foo,FOO 是不同的。查询词可以使用查询词查询接口进行获取。
text 文本
文本(或称之为全文)是普通的、非结构化的文本,例如本段话。默认情况下,文本将被分析为查询词,查询词将被保存在索引中。为能够进行全文搜索,文本字段在索引时将被分析为查询词,查询关键字在搜索时也将被分析为查询词,通过对比查询词是否相同而完成全文搜索。
type 类型
一种类型类似于关系型数据库中的一张表。每种类型都有若干字段,可以用于指定给该类型文档。映射定义了该文档中的每个字段如何进行分析。
参考
Elasticsearch Glossary of terms
全文搜索之 Elasticsearch的更多相关文章
- Elasticsearch全文搜索——adout
现在尝试下稍微高级点儿的全文搜索——一项传统数据库确实很难搞定的任务. 搜索下所有喜欢攀岩(rock climbing)的雇员: curl -XGET 'localhost:9200/megacorp ...
- 在 Laravel 项目中使用 Elasticsearch 做引擎,scout 全文搜索(小白出品, 绝对白话)
项目中需要搜索, 所以从零开始学习大家都在用的搜索神器 elasiticsearch. 刚开始 google 的时候, 搜到好多经验贴和视频(中文的, 英文的), 但是由于是第一次接触, 一点概念都没 ...
- 使用ElasticSearch服务从MySQL同步数据实现搜索即时提示与全文搜索功能
最近用了几天时间为公司项目集成了全文搜索引擎,项目初步目标是用于搜索框的即时提示.数据需要从MySQL中同步过来,因为数据不小,因此需要考虑初次同步后进行持续的增量同步.这里用到的开源服务就是Elas ...
- ASP.NET Web API + Elasticsearch 6.x 快速做个全文搜索
最近想做个全文搜索,设想用 ASP.NET Web API + Elasticsearch 6.x 来实现. 网上搜了下 Elasticsearch 的资料,大部分是讲 linux 平台下如何用 ja ...
- ElasticSearch 2 (14) - 深入搜索系列之全文搜索
ElasticSearch 2 (14) - 深入搜索系列之全文搜索 摘要 在看过结构化搜索之后,我们看看怎样在全文字段中查找相关度最高的文档. 全文搜索两个最重要的方面是: 相关(relevance ...
- 可以执行全文搜索的原因 Elasticsearch full-text search Kibana RESTful API with JSON over HTTP elasticsearch_action es 模糊查询
https://www.elastic.co/guide/en/elasticsearch/guide/current/getting-started.html Elasticsearch is a ...
- Elasticsearch 全文搜索
1,匹配查询(match) match查询主要的应用场景是进行全文搜索: // 1,初始化数据 DELETE /my_index PUT /my_index { "settings" ...
- Elasticsearch系列---深入全文搜索
概要 本篇介绍怎样在全文字段中搜索到最相关的文档,包含手动控制搜索的精准度,搜索条件权重控制. 手动控制搜索的精准度 搜索的两个重要维度:相关性(Relevance)和分析(Analysis). 相关 ...
- Elasticsearch构建全文搜索系统
目录 前言 一.安装 1.安装elasticsearch 2.启动集群cluster 3.安装管理界面elasticsearch-head 4.安装分词插件elasticsearch-analysis ...
随机推荐
- make TARGET_PRODUCT=am335xevm OMAPES=4.x rowboat_clean 出现sgx相关的错误
这些错误是一些链接错误,由于地址变更导致的软链接不对.所以只要更改下软链接的具体地址就可以.
- libmysql.dll 找不到
在用C#开发的时候,需要连接MySQL ,系统提示 libmysql.dll 找不到模块. 我们可以找到 MySQL安装文件夹下的 C:\Program Files\MySQL\MySQL Ser ...
- javascript语句语义大全(6)
var d = new Date();//创建当前日期对象var d = new Date('2016/03/22');//允许var d = new Date('2016/3/22');//允许va ...
- HDU 3038 How Many Answers Are Wrong (并查集)---并查集看不出来系列-1
Problem Description TT and FF are ... friends. Uh... very very good friends -________-bFF is a bad b ...
- UVA - 437 The Tower of Babylon(dp-最长递增子序列)
每一个长方形都有六种放置形态,其实可以是三种,但是判断有点麻烦直接用六种了,然后按照底面积给这些形态排序,排序后就完全变成了LIS的问题.代码如下: #include<iostream> ...
- synchronized关键字以及实例锁 类锁
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...
- 屏幕的尺寸(厘米)、屏幕分辨率(像素)、PPI它们之间是什么关系
屏幕的尺寸(厘米).屏幕分辨率(像素).PPI它们之间是什么关系? 添加评论 分享 赞同2反对,不会显示你的姓名 知乎用户,数据ETL,UNITY3D 刘大侠.如果 赞同 以iphone4 为例,分辨 ...
- ActiveMQ的配置与使用
1.什么是ActiveMQ MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来 ...
- 别说你不知道java中的包装类,wrapper type,以及容易在自动拆箱中出现的问题
很多时候,会有人问你,你知道什么是包装类吗? 或者高端一点问你你知道,wrapper type,是什么吗? 然后你就懵逼了,学了java很多时候都不知道这是啥. 其实问你的人,可能只是想问你,java ...
- Hibernate中,将session绑定到线程时,在保存和查询数据的代码里,要正确的关闭session
比如有个保存的方法 // 保存 public void save(){ Transaction t = XXX Session s = getSession.beginTransaction(); X ...