分布式搜索ElasticSearch
1、ElasticSearch 简介
ElasticSearch 是一个基于 Lucene 的搜索服务器。它是基于 RESTful web 接口的分布式全文搜索引擎。Elasticsearch 是用 Java 语言开发的,并作为 Apache 许可条款下的开放源码发布,是一种流行的企业级搜索引擎。ElasticSearch 用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
特性:
-
分布式的文档存储引擎
-
分布式的搜索引擎和分析引擎
-
分布式,支持PB级数据
使用场景:
-
搜索领域:如百度、谷歌,全文检索等。
-
门户网站:访问统计、文章点赞、留言评论等。
-
广告推广:记录员工行为数据、消费趋势、员工群体进行定制推广等。
-
信息采集:记录应用的埋点数据、访问日志数据等,方便大数据进行分析。
2、ElasticSearch 基础概念
2.1、ElaticSearch 和 DB 的关系
在 Elasticsearch 中,文档归属于一种类型 type,而这些类型存在于索引 index 中,我们可以列一些简单的不同点,来类比传统关系型数据库:
-
Relational DB -> Databases -> Tables -> Rows -> Columns
-
Elasticsearch -> Indices -> Types -> documents -> Fields
Elasticsearch 集群可以包含多个索引 indices,每一个索引可以包含多个类型 types,每一个类型包含多个文档 documents,然后每个文档包含多个字段 Fields。而在 DB 中可以有多个数据库 Databases,每个库中可以有多张表 Tables,没个表中又包含多行Rows,每行包含多列Columns。以关系型数据库来类比理解:
Elasticsearch
|
关系型数据库
|
Index
|
数据库实例
|
Type
|
表
|
Document
|
行
|
Field
|
列
|
假设我们的系统要存储商品信息。
-
首先“商品”这个概念就可以作为一个Index,比如我们叫它 mer_idx;
-
然后,商品有很多分类,比如日化商品、电器商品、生鲜商品,每一个分类我们把它作为一个Type,那么就有 mer_normal_type、 mer_elc_type、 mer_sea_type。
-
每一种Type分类下都有自己的一些商品信息document,这些商品信息的大部分Field都是相同的,比如商品ID、商品名称、数量、描述等等,但是每个分类又略有差别,比如电器商品类相比生鲜商品类,可能多了些电器参数字段Field。
2.2、索引
索引基本概念(indices):索引是含义相同属性的文档集合,是 ElasticSearch 的一个逻辑存储,可以理解为关系型数据库中的数据库,ElasticSearch 可以把索引数据存放到一台服务器上,也可以 sharding 后存到多台服务器上,每个索引有一个或多个分片,每个分片可以有多个副本。
索引类型(index_type):索引可以定义一个或多个类型,文档必须属于一个类型。在 ElasticSearch 中,一个索引对象可以存储多个不同用途的对象,通过索引类型可以区分单个索引中的不同对象,可以理解为关系型数据库中的表。每个索引类型可以有不同的结构,但是不同的索引类型不能为相同的属性设置不同的类型。
2.3、文档
文档(document):文档是可以被索引的基本数据单位。存储在 ElasticSearch 中的主要实体叫文档 document,可以理解为关系型数据库中表的一行记录。每个文档由多个字段构成,ElasticSearch 是一个非结构化的数据库,每个文档可以有不同的字段,并且有一个唯一的标识符。
2.4、映射
映射(mapping):ElasticSearch 的 Mapping 非常类似于静态语言中的数据类型:声明一个变量为 int 类型的变量,以后这个变量都只能存储 int 类型的数据。同样的,一个 number 类型的 mapping 字段只能存储 number 类型的数据。同语言的数据类型相比,Mapping 还有一些其他的含义,Mapping 不仅告诉 ElasticSearch 一个 Field 中是什么类型的值, 它还告诉 ElasticSearch 如何索引数据以及数据是否能被搜索到。
ElaticSearch 默认是动态创建索引和索引类型的 Mapping 的。这就相当于无需定义 Solr 中的 Schema,无需指定各个字段的索引规则就可以索引文件,很方便。但有时方便就代表着不灵活。比如,ElasticSearch 默认一个字段是要做分词的,但我们有时要搜索匹配整个字段却不行。如有统计工作要记录每个城市出现的次数。对于 name 字段,若记录 new york 文本,ElasticSearch 可能会把它拆分成 new 和 york 这两个词,分别计算这个两个单词的次数,而不是我们期望的 new york。
2.5、操作ES的RESTFul接口
GET请求
http://ip:port/index 查询索引
http://ip:port/index/type/doc_id 查询具体的文档索引
http://ip:port/index/type/_search:查询文档,可以在请求体添加json添加查询
POST请求
http://ip:port/index/type/_update:修改文档,在请求体中添加json格式的修改条件
PUT请求
http://ip:port/index:创建一个索引,需要在请求体中指定索引信息
http://ip:port/index/type/_mappings :创建索引,指定索引的文档中存储属性信息
DELETE请求
http://ip:port/index:删除所有
2.6、索引操作
1、创建索引
PUT /person { "settings": { "number_of_shards": 5, "number_of_replicas": 1 } }
2、查询索引
GET /person
3、删除索引
DELETE /person
2.7、ES中字段的类型
字符串类型:
-
text:可以用于全文检索,进行分词
-
keyword:不被进行分词
数值类型
-
long:占8个字节
-
integer:占4个字节
-
short:占2个字节
-
byte:占1个字节
-
double:占8个字节
-
float:4个字节
-
half_float :2个字节
-
scaled_float :根据一个long和scaled来表达一个浮点类型 long 123 scaled:100->1.23
时间类型
-
date
布尔类型
-
booleanl类型,true/false
二进制类型
-
binary:但是存储是需要将二进制转换成Base64编码格式的字符串
范围类型greater than/less than equals
-
integer_range:赋值的时候,,不需要给定具体的值,给一个integer范围就可以了:
-
gte/lte/gt/lt
-
float_range:
-
long_range:
-
double_range:
-
date_range:
-
ip_range:
经纬度类型:
-
geo-point:存储经纬度
ip类型:
-
ip:可以存Ipv4或者Ipv6
2.8、文档操作
在es服务中唯一标识符, _index , _type , _id 三个内容的组合,来确定一个具体的文档。
1、添加文档
id自动生成
#添加文档,自动生成文档id POST /book/novel { "name":"西游记", "author":"吴承恩", "price":8888, "count":100, "pubdate":"2022-8-19 12:12:12", "decr":"你这泼猴,我要再压你五百年!" }
手动添加id
#添加文档,手动指定id POST /book/novel/2 { "name":"三国演义", "author":"罗贯中", "price":2789, "count":100, "pubdate":"2020-8-19 12:12:12", "decr":"再活五百年,我就成仙了" }
2、修改文档
指定文档id PUT /book/novel/3 { "name":"红楼梦", "author":"曹雪芹", "price":1000, "count":100, "pubdate":"2020-8-19 12:12:12", "decr":"美女和野兽" }
基于doc方式进行修改
#_update表示修改 POST /book/novel/3/_update { "doc":{ #指定需要修改的字段 字段名:对应的值 "decr":"假作真时真亦假" } }
3、删除文档
根据id删除:
DELETE /book/novel/_id