1.走进ElasticSearch
一.全文检索
- 为什么要使用全文检索
- 用户访问我们的首页,一般都会直接搜索来寻找自己想要购买的商品。而商品的数量非常多,而且分类繁杂。如果能正确的显示出用户想要的商品,并进行合理的过滤,尽快促成交易,是搜索系统要研究的核心。
- 面对这样复杂的搜索业务和数据量,使用传统数据库搜索就显得力不从心,一般我们都会使用全文检索技术。
常见的全文检索技术有 Lucene、solr 、elasticsearch 等。
- 理解索引结构
- 下图是索引结构,下边黑色部分是物理结构,上边黄色部分是逻辑结构,逻辑结构也是为了更好的去描述工作原理及去使用物理结构中的索引文件。
- 逻辑结构部分是一个倒排索引表:
1、将要搜索的文档内容分词,所有不重复的词组成分词列表。
2、将搜索的文档最终以Document方式存储起来。
3、每个词和docment都有关联。
- 下图是索引结构,下边黑色部分是物理结构,上边黄色部分是逻辑结构,逻辑结构也是为了更好的去描述工作原理及去使用物理结构中的索引文件。
二.Elasticsearch
- Elasticsearch简介
- ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
- 我们建立一个网站或应用程序,并要添加搜索功能,但是想要完成搜索工作的创建是非常困难的。我们希望搜索解决方案要运行速度快,我们希望能有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用JSON通过HTTP来索引数据,我们希望我们的搜索服务器始终可用,我们希望能够从一台开始并扩展到数百台,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。因此我们利用Elasticsearch来解决所有这些问题及可能出现的更多其它问题。
官方网址:https://www.elastic.co/cn/products/elasticsearch
Github:https://github.com/elastic/elasticsearch - 优点:
(1)可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司;也可以运行在单机上
(2)将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;
(3)开箱即用的,部署简单
(4)全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理
下表是Elasticsearch与MySQL数据库逻辑结构概念的对比
- 安装与启动
下载ElasticSearch 6.5.2版本
https://www.elastic.co/downloads/past-releases/elasticsearch-6.5.2
在命令提示符下,进入ElasticSearch安装目录下的bin目录,执行命令即可启动
我们打开浏览器,在地址栏输入http://127.0.0.1:9200/ 即可看到输出结果
三.使用Postman操作索引库
- 新建文档
使用postman测试:以post方式提交 http://127.0.0.1:9200/testindex/doc
body:
返回结果如下: - 查询文档
查询某索引某类型的全部数据,以get方式请求http://127.0.0.1:9200/testindex/doc/_search
四.映射与数据类型
- 映射(Mapping)相当于数据表的表结构。ElasticSearch中的映射(Mapping)用来定义一个文档,可以定义所包含的字段以及字段的类型、分词器及属性等等。映射可以分为动态映射和静态映射。
- 动态映射 (dynamic mapping):在关系数据库中,需要事先创建数据库,然后在该数据库实例下创建数据表,然后才能在该数据表中插入数据。而ElasticSearch中不需要事先定义映射(Mapping),文档写入ElasticSearch时,会根据文档字段自动识别类型,这种机制称之为动态映射。
- 静态映射 :在ElasticSearch中也可以事先定义好映射,包含文档的各个字段及其类型等,这种方式称之为静态映射。
- 字符串类型
- 整数类型
- 浮点类型
- date类型
日期类型表示格式可以是以下几种:
(1)日期格式的字符串,比如 “2018-01-13” 或 “2018-01-13 12:10:30”
(2)long类型的毫秒数( milliseconds-since-the-epoch,epoch就是指UNIX诞生的UTC时间1970年1月1日0时0分0秒)
(3)integer的秒数(seconds-since-the-epoch) - boolean类型
逻辑类型(布尔类型)可以接受true/false - binary类型
二进制字段是指用base64来表示索引中存储的二进制数据,可用来存储二进制形式的数据,例如图像。默认情况下,该类型的字段只存储不索引。二进制类型只支持index_name属性。 - array类型
- 在ElasticSearch中,没有专门的数组(Array)数据类型,但是,在默认情况下,任意一个字段都可以包含0或多个值,这意味着每个字段默认都是数组类型,只不过,数组类型的各个元素值的数据类型必须相同。在ElasticSearch中,数组是开箱即用的(out ofbox),不需要进行任何配置,就可以直接使用。
- 在同一个数组中,数组元素的数据类型是相同的,ElasticSearch不支持元素为多个数据类型:[ 10, “some string” ],常用的数组类型是:
(1)字符数组: [ “one”, “two” ]
(2)整数数组: productid:[ 1, 2 ]
(3)对象(文档)数组: “user”:[ { “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”:10 }],ElasticSearch内部把对象数组展开为 {“user.name”: [“Mary”, “John”], “user.age”:[12,10]}
- object类型
JSON天生具有层级关系,文档会包含嵌套的对象
五.IK分词器
- 什么是IK分词器
默认的中文分词是将每个字看成一个词,这显然是不符合要求的,所以我们需要安装中文分词器来解决这个问题。
IK分词是一款国人开发的相对简单的中文分词器。虽然开发者自2012年之后就不在维护了,但在工程应用中IK算是比较流行的一款!我们今天就介绍一下IK中文分词器的使用。 - IK分词器安装
下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases 下载6.5.2版本
(1)先将其解压,将解压后的elasticsearch文件夹重命名文件夹为ik
(2)将ik文件夹拷贝到elasticsearch/plugins 目录下。
(3)重新启动,即可加载IK分词器 - IK分词器测试
IK提供了两个分词算法ik_smart 和 ik_max_word
其中 ik_smart 为最少切分,ik_max_word为最细粒度划分 - 自定义词库
(1)进入elasticsearch/plugins/ik/config目录
(2)新建一个my.dic文件,编辑内容: 自定义的词
修改IKAnalyzer.cfg.xml(在ik/config目录下)
六.Kibana
- Kibana简介
Kibana 是一个开源的分析和可视化平台,旨在与 Elasticsearch 合作。Kibana 提供搜索、查看和与存储在 Elasticsearch 索引中的数据进行交互的功能。开发者或运维人员可以轻松地执行高级数据分析,并在各种图表、表格和地图中可视化数据。 - Kibana安装与启动
(1)解压 资料\配套软件\elasticsearch\kibana-6.5.2-windows-x86_64.zip
(2)如果Kibana远程连接Elasticsearch ,可以修改config\kibana.yml
(3)执行bin\kibana.bat
(4)打开浏览器,键入http://localhost:5601 访问Kibana
我们这里使用Kibana进行索引操作,Kibana与Postman相比省略了服务地址,并且有语法提示,非常便捷。
2.索引操作
一.创建索引与映射字段
- 请求方式依然是PUT
类型名称:就是前面将的type的概念,类似于数据库中的不同表
字段名:任意填写,可以指定许多属性,例如:
type:类型,可以是text、long、short、date、integer、object等
index:是否索引,默认为true
store:是否单独存储,默认为false ,一般内容比较多的字段设置成true,可提升查询性能
analyzer:分词器 - 发起请求
- 响应结果
二.文档增加与修改
- 增加文档自动生成ID
通过POST请求,可以向一个已经存在的索引库中添加数据。
通过以下命令查询sku索引的数据 - 新增文档指定ID
三.索引查询
- 基本语法
这里的query代表一个查询对象,里面可以有不同的查询属性
查询类型:
例如: match_all , match , term , range 等等
查询条件:查询条件会根据类型的不同,写法也有差异 - 查询所有数据(match_all)
示例: - 匹配查询(match)
示例:查询名称包含手机的记录
如果我们需要精确查找,也就是同时包含小米和电视两个词的才可以查询出来,这就需要将操作改为 and 关系: - 多字段查询(multi_match)
multi_match 与 match类似,不同的是它可以在多个字段中查询 - 词条匹配(term)
term查询被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字符串 - 多词条匹配(terms)
terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件: - 布尔组合(bool)
bool 把各种其它查询通过 must (与)、 must_not (非)、 should (或)的方式进行组合
示例:查询名称包含手机的,并且品牌为小米的。 - 过滤查询
过滤是针对搜索的结果进行过滤,过滤器主要判断的是文档是否匹配,不去计算和判断文档的匹配度得分,所以过滤器性能比查询要高,且方便缓存,推荐尽量使用过滤器去实现查询或者过滤器和查询共同使用。
示例:过滤品牌为小米的记录 - 分组查询
示例:按分组名称聚合查询,统计每个分组的数量
size为0 不会将数据查询出来,目的是让查询更快。
3.JavaRest 高级客户端入门
一.JavaRest 高级客户端简介
- elasticsearch 存在三种Java客户端。
1. Transport Client
2. Java Low Level Rest Client(低级rest客户端)
3. Java High Level REST Client(高级rest客户端) - 这三者的区别是:
- TransportClient没有使用RESTful风格的接口,而是二进制的方式传输数据。
- ES官方推出了Java Low Level REST Client,它支持RESTful。但是缺点是因为TransportClient的使用者把代码迁移到Low Level REST Client的工作量比较大。
- ES官方推出Java High Level REST Client,它是基于Java Low Level REST Client的封装,并且API接收参数和返回值和TransportClient是一样的,使得代码迁移变得容易并且支持了RESTful的风格,兼容了这两种客户端的优点。强烈建议ES5及其以后的版本使用Java High Level REST Client。
- 准备工作:新建工程,引入依赖
二.快速入门
- 新增和修改数据
插入单条数据:
HttpHost : url地址封装
RestClientBuilder: rest客户端构建器
RestHighLevelClient: rest高级客户端
IndexRequest: 新增或修改请求
IndexResponse:新增或修改的响应结果
如果ID不存在则新增,如果ID存在则修改。
批处理请求:
BulkRequest: 批量请求(用于增删改操作)
BulkResponse:批量请求(用于增删改操作) - 匹配查询
SearchRequest: 查询请求对象
SearchResponse:查询响应对象
SearchSourceBuilder:查询源构建器
MatchQueryBuilder:匹配查询构建器 - 布尔与词条查询
BoolQueryBuilder:布尔查询构建器
TermQueryBuilder:词条查询构建器
QueryBuilders:查询构建器工厂 - 过滤查询
- 分组(聚合)查询
AggregationBuilders:聚合构建器工厂
TermsAggregationBuilder:词条聚合构建器
Aggregations:分组结果封装
Terms.Bucket: 桶
4.批量数据导入
一.需求分析
- 单独建立工程,实现青橙商品索引数据的批量导入。
二.实现思路
- 建立工程,引入通用mapper 和elasticsearch依赖
- 查询sku表数据,将集合数据循环插入到elasticsearch中