百度:我们比如说想找寻任何的信息的时候,就会上百度去搜索一下,比如说找一部自己喜欢的电影,或者说找一本喜欢的书,或者找一条感兴趣的新闻(提到搜索的第一印象)。百度!=搜索
1)互联网的搜索:电商网站,招聘网站,新闻网站,各种app
2)IT系统的搜索:OA软件,办公自动化软件,会议管理,日程管理,项目管理。
用数据库来实现搜索,是不太靠谱的。通常来说,性能会很差
1)全文检索,倒排索引
2)lucene,就是一个jar包,里面包含了封装好的各种建立倒排索引,以及进行搜索的代码,包括各种算法。我们就用java开发的时候,引入lucenejar,然后基于lucene的api进行去进行开发就可以了
可以看到Lucene为倒排索引(TermDictionary)部分又增加一层TermIndex结构,用于快速定位,而这TermIndex是缓存在内存中的,但MySQL的B+tree不在内存中,所以整体来看ES速度更快,但同时也更消耗资源(内存、磁盘)
ElasticSearch,基于Lucene,隐藏复杂性,提供简单易用的RestfulAPI接口、JavaAPI接口(还有其他语言的API接口),ElasticSearch是一个实时分布式搜索和分析引擎。它用于全文搜索、结构化搜索、分析。
关于ElasticSearch的一个传说,有一个程序员失业了,陪着自己老婆去英国伦敦学习厨师课程。程序员在失业期间想给老婆写一个菜谱搜索引擎,觉得Lucene实在太复杂了,就开发了一个封装了Lucene的开源项目:Compass。后来程序员找到了工作,是做分布式的高性能项目的,觉得Compass不够,就写了ElasticSearch,让Lucene变成分布式的系统。
全文检索:将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。
结构化检索:我想搜索商品分类为日化用品的商品都有哪些,select*fromproductswherecategory_id='日化用品'。
数据分析:电商网站,最近7天牙膏这种商品销量排名前10的商家有哪些;新闻网站,最近1个月访问量排名前3的新闻版块是哪些。
1)维基百科,类似百度百科,牙膏,牙膏的维基百科,全文检索,高亮,搜索推荐。
4)GitHub(开源代码管理),搜索上千亿行代码。
1)天然分片,天然集群,ES把数据分成多个shard,下图中的P0-P2,多个shard可以组成一份完整的数据,这些shard可以分布在集群中的各个机器节点中。随着数据的不断增加,集群可以增加多个分片,把多个分片放到多个机子上,已达到负载均衡,横向扩展。
2)ElasticSearch不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;lucene(全文检索),商用的数据分析软件(也是有的),分布式数据库(mycat)
3)对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分钟部署一下ES,就可以作为生产环境的系统来使用了,数据量不大,操作不是太复杂
近实时,两个意思,从写入数据到数据可以被搜索到有一个小延迟(大概1秒);基于es执行搜索和分析可以达到秒级。
集群包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称,默认是elasticsearch)来决定的,对于中小型应用来说,刚开始一个集群就一个节点很正常
集群中的一个节点,节点也有一个名称(默认是随机分配的),节点名称很重要(在执行运维管理操作的时候),默认节点会去加入一个名称为“elasticsearch”的集群,如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群。
索引包含一堆有相似结构的文档数据,比如可以有一个客户索引,商品分类索引,订单索引,索引有一个名称。一个index包含很多document,一个index就代表了一类类似的或者相同的document。比如说建立一个productindex,商品索引,里面可能就存放了所有的商品数据,所有的商品document。
6.0版本之前每个索引里都可以有多个type,6.0版本之后每个索引里面只能有一个Type,一般使用_doc代替了。
商品index,里面存放了所有的商品数据,商品document
商品type:product_id,product_name,product_desc,category_id,category_name,service_period
每一个type里面,都会包含一堆document
{"product_id":"1","product_name":"长虹电视机","product_desc":"4k高清","category_id":"3","category_name":"电器","service_period":"1年"}{"product_id":"2","product_name":"基围虾","product_desc":"纯天然,冰岛产","category_id":"4","category_name":"生鲜","eat_period":"7天"}1.7.6Document(文档-行)文档是ES中的最小数据单元,一个document可以是一条客户数据,一条商品分类数据,一条订单数据,通常用JSON数据结构表示,每个index下的type中,都可以去存储多个document。
一个document里面有多个field,每个field就是一个数据字段
productdocument{"product_id":"1","product_name":"高露洁牙膏","product_desc":"高效美白","category_id":"2","category_name":"日化用品"}1.7.8Mapping(映射-约束)数据如何存放到索引对象上,需要有一个映射配置,包括:数据类型、是否存储、是否分词等。
Mapping用来定义Document中每个字段的类型,即所使用的分词器、是否索引等属性,非常关键等。创建Mapping的代码示例如下:
PUTstudent(index_name->database){"mappings":{"_doc":{(type_name->table)"properties":{"stu_id":{(field_name->colume)"type":"keyword"},"name":{(field_name->colume)"type":"keyword"},"birth":{(field_name->colume)"type":"date"(yyyy-MM-ddHH:mm)}}}}}1.7.9ElasticSearch与数据库的类比关系型数据库(比如Mysql)
非关系型数据库(ElasticSearch)
数据库Database
索引Index
表Table
类型Type(6.0版本之后在一个索引下面只能有一个,7.0版本之后取消了Type)
数据行Row
文档Document(JSON格式)
数据列Column
字段Field
约束Schema
映射Mapping
1)索引对象(blog):存储数据的表结构,任何搜索数据,存放在索引对象上。
2)映射(mapping):数据如何存放到索引对象上,需要有一个映射配置,包括:数据类型、是否存储、是否分词等。
3)文档(document):一条数据记录,存在索引对象上。
4)文档类型(type):一个索引对象,存放多种类型数据,数据用文档类型进行标识。
2)下载Elasticsearch
3)由于后面我们需要用到Kibana,所以我们继续下载Kibana
4)由于后面我们需要用到IK分词器,所以我们继续下载IK分词
1)上传elasticsearch-6.6.0.tar.gz到hadoop104机器上的/opt/software目录下
2)解压elasticsearch-6.6.0.tar.gz到/opt/module目录下
tar-zxvf/opt/software/elasticsearch-6.6.0.tar.gz-C/opt/module/3)在/opt/module/elasticsearch-6.6.0目录下创建datas文件夹
cd/opt/module/elasticsearch-6.6.0mkdirdatas4)修改配置文件elasticsearch.yml
(2)nodename随意取但是集群内的各节点不能相同
(3)修改后的每行前面不能有空格,修改后的“:”后面必须有一个空格
5)修改配置文件jvm.options
vim/opt/module/elasticsearch-6.6.0/config/jvm.options#修改-Xms1g-Xmx1g#为-Xms256m-Xmx256m6)分发
xsync/opt/module/elasticsearch-6.6.0/7)分发完成后修改hadoop102和hadoop103主机的elasticsearch.yml文件中的node.name和network.host属性
2)分发
sudo/home/atguigu/bin/xsync/etc/security/limits.conf3)切换到root用户修改配置sysctl.conf,可以使用sudo
sudovim/etc/sysctl.conf#添加下面配置:vm.max_map_count=6553604)查看是否设置vm.max_map_count成功
5)分发
sudo/home/atguigu/bin/xsync/etc/sysctl.conf6)重启Linux虚拟机
#关机xcall.shshutdown-hnow7)重启虚拟机之后我们开始启动Elasticsearch(hadoop104上执行该命令)
9)新开一个hadoop104的shell窗口
10)停止Elasticsearch
#kill-9进程号kill-9182411)Elasticsearch集群启动/停止脚本
vim/home/atguigu/bin/elasticsearch.sh#!/bin/bashif(($#!=1))thenecho请输入单个start或stop参数!exitfi#对传入的单个参数进行校验,在hadoop102和hadoop103且执行第一层采集通道的启动和停止命令if[$1=start]thencmd="nohup/opt/module/elasticsearch-6.6.0/bin/elasticsearch>/dev/null2>&1&"elif[$1=stop]thencmd="ps-ef|grepElasticsearch|grep-vgrep|awk'{print\$2}'|xargskill"elseecho请输入单个start或stop参数!fi#在hadoop102和hadoop103且执行第一层采集通道的启动和停止命令foriinhadoop102hadoop103hadoop104doecho"--------------$i-----------------"ssh$i$cmdsleep8sdone12)赋予可执行权限
chmod+x/home/atguigu/bin/elasticsearch.sh13)分发脚本
xsync/home/atguigu/bin/elasticsearch.sh14)启动Elasticsearch集群
1)请求:
1)Kibana的安装,将kibana-6.6.0-linux-x86_64.tar.gz上传到hadoop104集群上的/opt/software目录中
2)解压kibana-6.6.0-linux-x86_64.tar.gz至/opt/module/
tar-zxvf/opt/software/kibana-6.6.0-linux-x86_64.tar.gz-C/opt/module/3)重命名
mv/opt/module/kibana-6.6.0-linux-x86_64//opt/module/kibana-6.6.04)修改kibana.yml,以连接Elasticsearch
7)修改之前的ES启动脚本为:
vim/home/atguigu/bin/elasticsearch.sh#!/bin/bashif(($#!=1))thenecho请输入单个start或stop参数!exitfies_home=/opt/module/elasticsearch-6.6.0kibana_home=/opt/module/kibana-6.6.0case$1in"start"){foriinhadoop102hadoop103hadoop104doecho"==============$i启动Elasticsearch=============="ssh$i"source/etc/profile;${es_home}/bin/elasticsearch>/dev/null2>&1&"sleep5s;donesleep2s;echo"==============hadoop104启动Kibana=============="sshhadoop104nohup${kibana_home}/bin/kibana>kibana.log2>&1&};;"stop"){sshhadoop104ps-ef|grep${kibana_home}|grep-vgrep|awk'{print$2}'|xargskillecho"==============hadoop104停止Kibana=============="foriinhadoop102hadoop103hadoop104dossh$i"ps-ef|grep$es_home|grep-vgrep|awk'{print\$2}'|xargskill">/dev/null2>&1echo"==============$i停止Elasticsearch=============="done};;esac8)分发脚本
xsync/home/atguigu/bin/elasticsearch.sh9)进入Kibana的DevTools,然后在操作窗口输入以下内容:
字符串型:text(分词)、keyword(不分词)
数值型:long、integer、short、byte、double、float、half_float、scaled_float
日期类型:date
布尔类型:boolean
二进制类型:binary
范围类型:integer_range、float_range、long_range、double_range、date_range
数组类型:array
对象类型:object
嵌套类型:nestedobject
geo_point(点)、geo_shape(形状)
记录IP地址:ip
实现自动补全:completion
记录分词数:token_count
记录字符串hash值:murmur3
多字段特性:multi-fields
1)创建操作
2)创建文档
3)查询
ES可以自动识别文档字段类型,从而降低用户使用成本
1)直接插入文档
2)查看mapping(birth自动识别为date类型,name识别为text类型)
3)日期类型的自动识别,可以自行配置日期格式,以满足各种需求
(1)自定义日期识别格式
PUTmy_index{"mappings":{"_doc":{"dynamic_date_formats":["yyyy-MM-dd","yyyy/MM/dd"]}}}(2)关闭日期自动识别
PUTmy_index2{"mappings":{"_doc":{"date_detection":false}}}4)字符串是数字时,默认不会自动识别为整形,因为字符串中出现数字时完全合理的,Numeric_datection可以开启字符串中数字的自动识别
分词器主要应用在中文上,在ES中字符串类型有keyword和text两种。keyword默认不进行分词,而text是将每一个汉字拆开称为独立的词,这两种都是不适用于生产环境,所以我们需要有其他的分词器帮助我们完成这些事情,其中IK分词器是应用最为广泛的一个分词器。
1)keyword类型的分词
2)text类型的分词
1)将下载好的elasticsearch-analysis-ik-6.6.0.zip上传至hadoop104机器的/opt/software目录
2)在/opt/module/elasticsearch-6.6.0/plugins目录下创建ik目录(名称随意起)
mkdir/opt/module/elasticsearch-6.6.0/plugins/ik3)解压elasticsearch-analysis-ik-6.6.0.zip至ik目录(若出现未找到unzip命令,则先安装)
sudoyuminstall-yunzipunzip/opt/software/elasticsearch-analysis-ik-6.6.0.zip-d/opt/module/elasticsearch-6.6.0/plugins/ik/4)分发分词器目录
xsync/opt/module/elasticsearch-6.6.0/plugins5)重新启动Elasticsearch,即可加载IK分词器
elasticsearch.shstopelasticsearch.shstart4.3.3IK分词器测试IK提供了两个分词算法ik_smart和ik_max_word,其中ik_smart为最少切分,ik_max_word为最细粒度划分。
1)最少划分ik_smart
2)最细切分ik_max_word
向Elasticsearch增加数据
PUTstudent{"mappings":{"_doc":{"properties":{"class_id":{"type":"keyword"},"stu_id":{"type":"keyword"},"name":{"type":"text"},"sex":{"type":"keyword"},"age":{"type":"integer"},"favo":{"type":"text","analyzer":"ik_max_word"}}}}}PUTstudent/_doc/1001{"class_id":"6001","stu_id":"2001","name":"花和尚","sex":"male","age":"29","favo":"吃肉,羊肉"}PUTstudent/_doc/1001{"class_id":"0821","stu_id":"001","name":"小花","sex":"female","age":18,"favo":"洗脚,海狗人参丸"}如果在关系型数据库Mysql中主键查询数据一般会执行下面的SQL语句
select*fromstudentwhereid=1001;但在Elasticsearch中需要采用特殊的方式
我们通过HTTP方法GET来检索文档,同样的,我们可以使用DELETE方法删除文档,使用HEAD方法检查某文档是否存在。如果想更新已存在的文档,我们只需再PUT一次
health
green(集群完整)yellow(单点正常、集群不完整)red(单点不正常)
status
是否能使用
index
索引名
uuid
索引统一编号
pri
主节点几个
rep
从节点几个
docs.count
文档数
docs.deleted
文档被删了多少
store.size
整体占空间大小
pri.store.size
主节点占空间大小
如果在关系型数据库Mysql中查询所有数据一般会执行下面的SQL语句
select*fromstu;但在Elasticsearch中需要采用特殊的方式
#协议方法索引/类型/_search
GETstu/_search响应内容不仅会告诉我们哪些文档被匹配到,而且这些文档内容完整的被包含在其中—我们在给用户展示搜索结果时需要用到的所有信息都有了
如果在关系型数据库Mysql中查询多字段匹配数据(字段检索)
一般会执行下面的SQL语句
select*fromstudentwheresex='male';但在Elasticsearch中需要采用特殊的方式,并且全值匹配会把查询条件当做一个整体来查。
没有对应的查询条件,因为ik_max_word分词器会把“海狗人参丸”分成以下词组
{"tokens":[{"token":"海狗","start_offset":0,"end_offset":2,"type":"CN_WORD","position":0},{"token":"人参","start_offset":2,"end_offset":4,"type":"CN_WORD","position":1},{"token":"丸","start_offset":4,"end_offset":5,"type":"CN_CHAR","position":2}]}我们会发现并没有“海狗人参丸”这几个字组合起来的词,因此查不到。
分词匹配会按照检索条件将其分词后再去匹配
GETstudent/_search{"query":{"match":{"favo":"海狗人参丸"}}}检索:ES的原理,从ES的倒排索引上检索指定分词对应的数据
切词:海狗人参丸=海狗,人参,人参丸
Select*Fromstudent.xWherefavolike‘%海狗%’orfavolike‘%人参%’orfavolike‘%人参丸%’4.4.5全值匹配和分词匹配结合使用GETstudent/_search{"query":{"bool":{"filter":{"term":{"sex":"female"}},"must":[{"match":{"favo":"海狗人参丸"}}]}}}4.4.6字段模糊匹配检索如果在关系型数据库Mysql中模糊查询多字段数据,一般会执行下面的SQL语句
select*fromstudentwherenamelike'%haha%'但在Elasticsearch中需要采用特殊的方式,查询出所有文档字段值分词后包含"我是程序"的文档
GETstudent/_search{"query":{"fuzzy":{"sex":"fmale"}}}4.4.7聚合检索4.4.7.1单聚合条件聚合查询相当于MySQL中的groupby
GETstudent/_search{"aggs":{"groupByClass":{"terms":{"field":"class_id.keyword","size":10}}}}4.4.7.2多聚合条件此时这两个聚合条件相互之间是没有关联的,比如同班级下的学生和年龄最大的学生
此时这两个聚合条件相互之间是有关联的,比如同班级下年龄最大的学生
如果想实现看某一页的内容,或者跳转到某一页显示出其内容,可以将from的值设置为((页面数-1)*size)
索引别名就像一个快捷方式或软连接,可以指向一个或多个索引,也可以给任何一个需要索引名的API来使用。别名带给我们极大的灵活性,允许我们做下面这些:
1)给多个索引分组(例如,last_three_months)
2)给索引的一个子集创建视图
3)在运行的集群中可以无缝的从一个索引切换到另一个索引
PUTmovie_index{"aliases":{"movie_chn_2021_query":{}},"mappings":{"movie_type":{"properties":{"id":{"type":"long"},"name":{"type":"text","analyzer":"ik_smart"}}}}}2)为已存在的索引增加别名
也可以通过加过滤条件缩小查询范围,建立一个子集视图
POST_aliases{"actions":[{"add":{"index":"student","alias":"student_query","filter":{"term":{"sex":"male"}}}}]}4.5.2查询别名与使用普通索引没有区别
IndexTemplate索引模板,顾名思义,就是创建索引的模具,其中可以定义一系列规则来帮助我们构建符合特定业务需求的索引的mappings和settings,通过使用IndexTemplate可以让我们的索引具备可预知的一致性。
这样做的好处有两个:
1)结构变化的灵活性:因为elasticsearch不允许对数据结构进行修改。但是实际使用中索引的结构和配置难免变化,那么只要对下一个间隔的索引进行修改,原来的索引位置原状。这样就有了一定的灵活性。
PUT_template/template_movie2021{"index_patterns":["movie_test"],"aliases":{"{index_query}":{},"movie_test_query":{}},"mappings":{"_doc":{"properties":{"id":{"type":"keyword"},"movie_name":{"type":"text","analyzer":"ik_smart"}}}}}其中"index_patterns":["movie_test*"],的含义就是凡是往movie_test开头的索引写入数据时,如果索引不存在,那么es会根据此模板自动建立索引。
在"aliases"中用{index}表示,获得真正的创建的索引名。
测试:
GET/test/emps/_searchGET/test/emps/_searchq=*GET/test/emps/_searchq=age:222)查询方式二,使用ES的DSL(特定领域语言)语法,将请求参数附加在请求体中