ElasticSearch搜索 1.Doug Cutting 美国工程师,迷上搜索引擎,做了Lucene,java编写,加入全文检索功能。
2.大数据两个问题:存储、计算
Lucene是一套信息检索工具包,jar包,不包含搜索引擎系统
3.ElasticSearch是基于Lucene做了一些封装和增强。 简称es,开源、高扩展得分布式全文 检索引擎。
数据分析:elasticsearch+logstash+klbana ELK技术
4.作用:高亮关键词、实时搜索、搜索纠错等 5.elasticsearch和solr的区别 6.ElasticSearch安装 最低要求JDK1.8+
下载官网:https://www.elastic.co/cn/
解压即用
双击bin/bat文件启动
解决:X-PACK IS NOT SUPPORTED AND MACHINE LEARNING IS NOT AVAILABLE FOR [WINDOWS-X86]
字面意思就是X-Pack不受我当前的win系统支持,需要在elasticsearch.yml 文件中加入一段代码xpack.ml.enabled: false elasticsearch.yml 在我们\elasticsearch-6.3.0\config目录下,打开后直接在末尾加上这段代码即可
访问http://127.0.0.1:9200
7.安装可视化界面head 依赖Node.js 下载地址:https://github.com/mobz/elasticsearch-head/
下载后进入D:\ElasticSearch\elasticsearch-head-master的CMD
敲命令:npm run start
‘grunt’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
1 2 npm install -g grunt-cli npm install grunt --save-dev
跨域访问:
elasticsearch.yml 在我们\elasticsearch-6.3.0\config目录下,打开后直接在末尾加上这段代码即可
1 2 http.cors.enabled:true http.cors.allow-origin:"*"
索引就是数据库
head是数据展示工具
8.安装kibana 管理elasticsearch
官网:https://www.elastic.co/cn/kibana
版本要和es的版本对应
汉化目录 config下kibana.yml,加上i18n.locale: “zh-CN”,重启项目
9.ES核心概念 面向 文档,和关系型数据库的对比,一起皆是json
关系型数据库
ElasticSearch
数据库(database)
索引(indices)
表(tables)
types(慢慢被弃用)
行(rows)
documents(文档)
字段(columns)
fields
物理设计:一个人就是集群,后台把每个索引分成多个分片,每个分片可以在集群中不同服务间迁移。
默认集群名称为:elasticsearch
文档
就是我们一条条数据。
面向文档,索引和搜索数据的最小单位是文档,属性:1.自我包含,一篇文档同时包含字段和对应的值,也同时包含key:value。2.可以是层次型的,文档可以包含文档。3.灵活的结构,文档不依赖于预先定义的模式,动态添加字段。
类型
不设置会自动猜,映射类型
字符串类型:text、keyword
数值类型:long、integer、short、byte、double、float、half float、scaled float
日期类型:date
布尔类型:boolean
二进制类型:binary
索引
就是数据库。
倒排索引
Lucene倒排索引作为底层,适用于快速全文索引。为了创建倒排索引,将每个文档拆分为独立的词,然后创建一个包含所有不重复的词条的排序列表,然后列出每个词条出现在哪个文档。看权重匹配。完全过滤掉无关的所有数据,提高效率!
一个es的索引由多个lucene索引构成。
10.IK分词器插件 分词:把一段段中文或者别的划分成一个个关键字。
搜索时把自己信息分词,把数据库或索引库分词,匹配。但是中文是把每个字分词一个词,不符合要求,需要安装中文分词器ik来解决。
ik提供两个分词算法:ik_smart和ik_max_word,其中ik_smart为最少切分,ik_max_word为最细粒度划分。
安装
下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases
下载解压后放在es目录下的pulgin下,重启es
1 2 D:\ElasticSearch\elasticsearch-7.15.2\bin>elasticsearch-plugin list 查看加载进的插件
操作
1.ik_smart最少切分
1 2 3 4 5 6 7 GET _analyze { "analyzer": "ik_smart", "text": [ "中国共产党" ] }
1 2 3 4 5 6 7 8 9 10 11 { "tokens" : [ { "token" : "中国共产党", "start_offset" : 0, "end_offset" : 5, "type" : "CN_WORD", "position" : 0 } ] }
2.ik_max_word最细粒度划分
1 2 3 4 5 6 7 GET _analyze { "analyzer": "ik_max_word", "text": [ "中国共产党" ] }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 { "tokens" : [ { "token" : "中国共产党", "start_offset" : 0, "end_offset" : 5, "type" : "CN_WORD", "position" : 0 }, { "token" : "中国", "start_offset" : 0, "end_offset" : 2, "type" : "CN_WORD", "position" : 1 }, { "token" : "国共", "start_offset" : 1, "end_offset" : 3, "type" : "CN_WORD", "position" : 2 }, { "token" : "共产党", "start_offset" : 2, "end_offset" : 5, "type" : "CN_WORD", "position" : 3 }, { "token" : "共产", "start_offset" : 2, "end_offset" : 4, "type" : "CN_WORD", "position" : 4 }, { "token" : "党", "start_offset" : 4, "end_offset" : 5, "type" : "CN_CHAR", "position" : 5 } ] }
自定义词需要自己加到分词器字典中。
ik分词器增加自己的配置
D:\ElasticSearch\elasticsearch-7.15.2\plugins\ik\config
下的IKAnalyzer.cfg.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典 --> <entry key="ext_dict"></entry> <!--用户可以在这里配置自己的扩展停止词字典--> <entry key="ext_stopwords"></entry> <!--用户可以在这里配置远程扩展字典 --> <!-- <entry key="remote_ext_dict">words_location</entry> --> <!--用户可以在这里配置远程扩展停止词字典--> <!-- <entry key="remote_ext_stopwords">words_location</entry> --> </properties>
自建dic文件,输入需要添加的词语,然后在IKAnalyzer.cfg.xml中添加字典名
1 <entry key="ext_dict">xxx.dic</entry>
重启es。
11.Rest风格
方法
url地址
描述
PUT
localhost:9200/索引名/类型名称/文档id
创建指定文档
POST
localhost:9200/索引名/类型名称
创建随机文档
POST
localhost:9200/索引名/类型名称/文档id/_update
修改文档
DELETE
localhost:9200/索引名/类型名称/文档id
删除文档
GET
localhost:9200/索引名/类型名称/文档id
查询文档通过文档id
POST
localhost:9200/索引名/类型名称/_search
查询所有数据
12.关于索引得基本操作
操作
1.创建一个索引
PUT /索引名/类型名/文档id {请求体}
1 2 3 4 5 PUT /demo01/type1/1 { "name":"小德", "age": 20 }
2.指定字段类型,创建规则
1 2 3 4 5 6 7 8 9 10 11 12 13 PUT /demo02 { "mappings": { "properties": { "name": { "type": "text" }, "age": { "type": "long" } } } }
3.获得规则,索引具体信息
GET demo01
4.不指定类型,默认字段类型:_doc,一般不设置,或可以设置为__doc
1 2 3 4 5 PUT /demo3/_doc/1 { "name":"haha", "age":23 }
5.查看es默认,具体信息
6.修改索引,版本号会增加
1 2 3 4 5 6 POST /demo01/type1/1/_update { "doc":{ "name":"法外狂徒张三" } }
7.删除索引,根据请求判断删除所有还是文档记录
13.关于文档得基本操作(重点)
基本操作
1.添加数据
1 2 3 4 5 6 7 PUT /usersy/user/1 { "name":"张三", "age":23, "desc":"你好世界", "tags":["技术宅","直男","普信男"] }
2.查询数据
精确查询
1 GET usersy/user/_search?q=name:张三
3.更新数据,version加一
1 2 3 4 5 6 7 PUT /usersy/user/1 { "name":"张三", "age":23, "desc":"你好世界", "tags":["技术宅","直男","普信男"] }
或者:POST _update,推荐
1 2 3 4 5 6 7 POST /usersy/user/1/_update { "name":"张三", "age":23, "desc":"你好世界", "tags":["技术宅","直男","普信男"] }
复杂操作
复杂查询(排序、分页、高亮、模糊查询、精准查询)
1 2 3 4 5 6 7 8 GET usersy/user/_search { "query":{ "match": { "name":"张" } } }
hit :索引和文档得信息,查询得结果总数,查询出来的具体文档,”_score” : 0.9808291权重
结果过滤
1 2 3 4 5 6 7 8 9 GET usersy/user/_search { "query":{ "match": { "name":"张" } }, "_source":["name","desc"] }
排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 GET usersy/user/_search { "query":{ "match": { "name":"张" } }, "_source":["name","desc"], "sort":{ "age":{ "order":"asc" } } }
分页
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 GET usersy/user/_search { "query":{ "match": { "name":"张" } }, "_source":["name","desc"], "sort":{ "age":{ "order":"asc" } }, "from":0, 起始下标 "size":1 每页多少条 }
数据下标从0开始
布尔值查询(多条件查询)
must(and)所有条件都符合
should(or)其中一个满足即可
must_not(not)不必需
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 GET usersy/user/_search { "query":{ "bool": { "must":[{ "match": { "name": "张" } }, { "match": { "age": "23" } }] } } }
过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 GET usersy/user/_search { "query": { "bool": { "must": { "match": { "name": "张" } }, "filter": { "range": { "age": { "gte": 5, "lte": 20 } } } } } }
gt:大于、lt:小于、gte:大于等于、lte:小于等于
匹配多个条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 GET usersy/user/_search { "query":{ "match": { "tags":"男" } } } GET usersy/user/_search { "query":{ "match": { "tags":"男 技术" } } } 多个条件用空格隔开,满足一个结果可以查出
精确查询
term查询直接通过倒排索引指定得词条进程精确查找
analyzer 两个类型 text keyword
keyword:不会被分析
1 2 3 4 5 6 7 8 GET usersy/user/_search { "query":{ "term": { "name":"张" } } }
多个值匹配得精确查询
用布尔查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 GET usersy/user/_search { "query": { "bool": { "must": [ { "match": { "name": "张三" } }, { "match": { "age": 23 } } ] } } }
高亮查询
1 2 3 4 5 6 7 8 9 10 11 12 13 GET usersy/user/_search { "query": { "match": { "name": "张" } }, "highlight":{ "fields": { "name":{} } } }
自定义高亮
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 GET usersy/user/_search { "query": { "match": { "name": "张" } }, "highlight": { "pre_tags": "<b>", "post_tags": "</b>", "fields": { "name": {} } } }
14.SpringBoot集成ElasticSearch7.x 1.找到原生的依赖Java REST Client-> Java High Level REST Client
https://www.elastic.co/guide/en/elasticsearch/client/index.html
1 2 3 4 5 <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.15.2</version> </dependency>
2.找对象
1 2 3 4 RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 9201, "http")));
3.分析类中方法
配置基本项目
Maven中记得改es版本
1 2 <properties> <elasticsearch.version>7.15.2</elasticsearch.version> </properties>
15.SpringBoot中关于索引的基本操作 1.创建索引
1 2 3 4 5 //创建索引请求 CreateIndexRequest req = new CreateIndexRequest("stu"); //执行请求,请求后获得响应 CreateIndexResponse resp = restHighLevelClient.indices().create(req, RequestOptions.DEFAULT); System.out.println(resp.isAcknowledged());
2.判断索引是否存在
1 2 3 4 5 // //获取索引请求 GetIndexRequest req = new GetIndexRequest("demo01"); // //执行请求,请求后获得响应 boolean exists = restHighLevelClient.indices().exists(req, RequestOptions.DEFAULT); System.out.println(exists);
3.删除索引
1 2 3 4 5 //删除索引请求 DeleteIndexRequest req = new DeleteIndexRequest("www"); //执行请求,请求后获得响应 AcknowledgedResponse resp = restHighLevelClient.indices().delete(req, RequestOptions.DEFAULT); System.out.println(resp.isAcknowledged());
16.SpringBoot中关于文档的基本操作 1.添加文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 //创建对象 User user=new User(1,"红火",23); //创建请求 IndexRequest req=new IndexRequest("usersy"); //规则 req.id("1"); req.timeout(TimeValue.timeValueSeconds(1)); req.timeout("1s"); //将数据放入请求 req.source(JSON.toJSONString(user), XContentType.JSON); //获取响应信息 IndexResponse resp = restHighLevelClient.index(req, RequestOptions.DEFAULT); System.out.println(resp.toString()); System.out.println(resp.status());
2.判断文档是否存在
1 2 3 4 5 6 7 GetRequest req=new GetRequest("usersy","1"); //忽略source req.fetchSourceContext(new FetchSourceContext(false)); //忽略排序 req.storedFields("_none_"); boolean exists = restHighLevelClient.exists(req, RequestOptions.DEFAULT); System.out.println(exists);
3.获取文档信息
1 2 3 4 GetRequest req=new GetRequest("usersy","1"); GetResponse resp = restHighLevelClient.get(req, RequestOptions.DEFAULT); System.out.println(resp.getSourceAsString()); System.out.println(resp);
4.更改文档信息
1 2 3 4 5 6 UpdateRequest req = new UpdateRequest("usersy","1"); req.timeout("1s"); User user=new User(1,"雄安",55); req.doc(JSON.toJSONString(user),XContentType.JSON); UpdateResponse resp = restHighLevelClient.update(req, RequestOptions.DEFAULT); System.out.println(resp.status());
5.删除文档信息
1 2 3 4 DeleteRequest req = new DeleteRequest("usersy","1"); req.timeout("1s"); DeleteResponse resp = restHighLevelClient.delete(req, RequestOptions.DEFAULT); System.out.println(resp.status());
6.批量添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 BulkRequest breq = new BulkRequest(); breq.timeout("10s"); ArrayList<User> users = new ArrayList<>(); users.add(new User(5, "赵六", 20)); users.add(new User(6, "无物", 19)); users.add(new User(7, "钱七", 16)); for (int i = 0; i < users.size(); i++) { breq.add(new IndexRequest("usersy") .id("" + i + 1) .source(JSON.toJSONString(users.get(i)), XContentType.JSON) ); } BulkResponse resp = restHighLevelClient.bulk(breq, RequestOptions.DEFAULT); System.out.println(resp.hasFailures());//是否失败
//查询文档
1 2 3 4 5 6 7 8 9 10 11 12 SearchRequest req = new SearchRequest("usersy"); //构建搜索条件 SearchSourceBuilder ssb = new SearchSourceBuilder(); TermQueryBuilder query = QueryBuilders.termQuery("name", "钱七"); ssb.query(query); ssb.timeout(new TimeValue(60, TimeUnit.SECONDS)); req.source(ssb); SearchResponse resp = restHighLevelClient.search(req, RequestOptions.DEFAULT); System.out.println(JSON.toJSONString(resp.getHits())); for (SearchHit searchHit:resp.getHits().getHits()){ System.out.println(searchHit.getSourceAsMap()); }