目录结构:

一、es概述

二、es安装/head插件安装/kibana安装

三、es核心概念

四、IK分词器

五、RestFul操作

六、CRUD(增删改查)

七、Springboot集成es

---------------------------------------分割线:正文--------------------------------------------------------

一、es概述

1、Doug Cutting

(1)创建了Lucene,(es与solr基于Lucene), 开源且功能为一套信息检索工具包,jar包

(2)实现了NDFS(分布式文件存储系统)基于Google的GFS系统

(3)将NDFS与MapReduce升级改造,重新命名为Hadoop,hadoop之父

(4)基于Google的BigTable,实现了HBase

2、ElasticSearch概述 

(1)概念:开源的分布式全文检索引擎

(2)优点:近乎实时存储、检索数据,扩展性好,可扩展上百台服务器,处理PB级别的数据,基于Lucene核心,通过RestFul API使全文搜索变得简单

(3)谁在使用:维基百科,搜狐新闻,Github等等

3、ES与solr的区别

(1)ES是RestFul API,而Solr是WebService API

(2)单纯已有的数据搜索,solr更快

(3)建立索引后的数据,Solr会产生io阻塞,es有明显的优势

(4)数据量增加,Solr的搜索效率会变低,es不受影响

 

二、es安装/head插件安装/kibana安装

声明:安装条件,JDK1.8+

 1、es下载:

(1)es客户端:https://www.elastic.co/cn/downloads/elasticsearch

(2)ik分词器:https://github.com/medcl/elasticsearch-analysis-ik/releases

(3)kibana:https://www.elastic.co/cn/downloads/kibana

(4)head插件:https://github.com/mobz/elasticsearch-head/archive/master.zip

(5)chrome-es插件:https://github.com/mobz/elasticsearch-head/blob/master/crx/es-head.crx

2、es客户端windows安装

(1)安装步骤

elasticsearch-7.12.1-windows-x86_64.zip 解压即可。

(2)相关文件

bin:启动文件

config:配置文件

- - log4j2.properties:日志配置

- - elasticsearch.yml:es配置文件,默认9200端口

- - jvm.options:java虚拟机相关配置

lib:相关jar包

modules:功能模块

plugins:插件!如ik分词器等

logs:日志

(3)启动es

双击bin目录下elasticsearch.bat

启动成功,默认访问9200端口

浏览器访问:http://127.0.0.1:9200/ 返回相关配置信息

3、安装可视化界面:es head的插件

(1)解压缩:elasticsearch-head-master.zip

(2)安装node.js:https://nodejs.org/en/

cmd:node -v验证安装成功

(3)安装cnpm:

cmd安装淘宝镜像:npm install -g cnpm -registry=https://registry.npm.taobao.org

cnpm -v验证安装成功

(4)安装依赖:

进入D:\elasticsearch\elasticsearch-head-master目录;执行cnpm install;

(5)运行npm run start启动npm

(6)浏览器访问:http://localhost:9100

由于跨域无法访问:

(7)配置可跨域

配置conf下elasticsearch.yml新增配置

http.cors.enabled: true
http.cors.allow-origin: "*"

重启es服务,再次访问,集群连接正常

4、Kibana安装

(1)Kibana安装的版本要与es版本对应:

(2)启动测试:运行bin下kibana.bat并测试对应的接口

(3)开发工具 http://localhost:5601

(4)配置中文:config下kibana.yml,新增配置并重启服务

i18n.locale: "zh-CN"

三、es核心概念

 1、elasticsearch是面向文档的(一切都是json),与关系型数据库的对比

RelationDB  -> Elasticsearch

数据库(database) -> 索引(indices)

表(tables) -> types(慢慢会被弃用)

行(rows) -> documents

字段(columns) -> fields

2、es物理设计:

elasticsearch在后台把每个索引划分成多个分片,每个分片在集群中的不同的服务间迁移。

默认的集群名就是elasticsearch

3、逻辑设计:

(1)文档:最小单位,即一条条数据

(2)类型:text、date等类型

(3)索引:数据库

4、es字段类型:

text:会被分词器解析

keyword:不会被分词器解析

四、IK分词器

1、分词:

把一段中文或别的划分为一个个关键字,我们在搜索时候会把自己的信息进行分词,默认的中文分词器将每个字看成一个词,我们需安装使用中文分词器ik来解决

2、安装ik分词器:

(1)下载:https://github.com/medcl/elasticsearch-analysis-ik/releases

(2)安装:elasticsearch-analysis-ik-7.12.1.zip放入elasticsearch-7.12.1\plugins目录下解压缩即可使用:

(3)重启观察ES,加载插件成功

[2021-05-12T23:00:05,420][INFO ][o.e.p.PluginsService     ] [DESKTOP-GIEVO4Q] loaded plugin [analysis-ik]
[2021-05-12T23:00:05,615][INFO ][o.e.e.NodeEnvironment ] [DESKTOP-GIEVO4Q] using [1] data paths, mounts [[杞欢 (D:)]], net usable_space [179.3gb], net total_space [300.7gb], types [NTFS]

(4)验证通过:elasticsearch-plugin list

D:\elasticsearch\elasticsearch-7.12.1\bin>elasticsearch-plugin list
"warning: usage of JAVA_HOME is deprecated, use ES_JAVA_HOME"
Future versions of Elasticsearch will require Java 11; your Java version from [C:\Program Files\Java\jdk1.8.0_271\jre] does not meet this requirement. Consider switching to a distribution of Elasticsearch with a bundled JDK. If you are already using a distribution with a bundled JDK, ensure the JAVA_HOME environment variable is not set.
ik

3、使用kibana进行测试

启动kibana进入控制台进行测试

查看不同的分词器效果

(1)ik_smart

GET _analyze
{
"analyzer": "ik_smart",
"text":"软件工程师"
}

查看运行结果:

{
"tokens" : [
{
"token" : "软件",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "工程师",
"start_offset" : 2,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 1
}
]
}

(2)ik_max_word

GET _analyze
{
"analyzer": "ik_max_word",
"text":"软件工程师"
}

查看运行结果:

{
"tokens" : [
{
"token" : "软件工程",
"start_offset" : 0,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "软件",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "工程师",
"start_offset" : 2,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "工程",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "师",
"start_offset" : 4,
"end_offset" : 5,
"type" : "CN_CHAR",
"position" : 4
}
]
}

4、将加入自己需要的词加到分词器的字典中

打开:elasticsearch-7.12.1\plugins\ik\config\IKAnalyzer.cfg.xml,配置<entry key="ext_dict"></entry>内添加字段映射

(1)配置前

GET _analyze
{
"analyzer": "ik_max_word",
"text":"我的妈"
}

查看运行结果:

{
"tokens" : [
{
"token" : "我",
"start_offset" : 0,
"end_offset" : 1,
"type" : "CN_CHAR",
"position" : 0
},
{
"token" : "的",
"start_offset" : 1,
"end_offset" : 2,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "妈",
"start_offset" : 2,
"end_offset" : 3,
"type" : "CN_CHAR",
"position" : 2
}
]
}

(2)配置

<entry key="ext_dict">my.dic</entry>

同目录下新增my.dic -> 我的妈

(3)配置后重启es,控制台

{
"tokens" : [
{
"token" : "我的妈",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 0
}
]
}

查看运行结果:

{
"tokens" : [
{
"token" : "我的妈",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 0
}
]
}

五、RestFul索引基本操作

 1、基本Rest命令:

PUT        |  localhost:9200/索引名称/类型名称/文档id                |   创建文档(指定文档id)

POST     |  localhost:9200/索引名称/类型名称                          |    创建文档(随机文档id)

POST     |  localhost:9200/索引名称/类型名称/文档id/_update |   修改文档

DELETE |  localhost:9200/索引名称/类型名称/文档id               |   删除文档

GET        |  localhost:9200/索引名称/类型名称/文档id               |   查询文档通过文档id

POST     |  localhost:9200/索引名称/类型名称/文档id/_search  |   查询所有文档

2、基础测试-创建索引

创建一个索引:PUT /索引名/~类型名~/文档id

PUT /test1/type1/1
{
"name":"小白学es",
"age":3
}

查看响应,完成自动增加了索引,类似数据库

#! [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).
{
"_index" : "test1",
"_type" : "type1",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}

3、基本数据类型

(1)字符串类型:text、keyword

(2)数值类型:long、integer、short、byte、double、half float、scaled、float

(3)日期类型:date

(4)te布尔类型:boolean

(5)二进制类型:binary

4、基础测试-创建并指定索引类型

PUT /test2
{
"mappings":{
"properties": {
"name":{
"type":"text"
},
"age":{
"type":"long"
},
"birthday":{
"type":"date"
}
}
}
}

查看运行结果

{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "test2"
}

5、 基础测试-创建/查看默认信息

(1)创建默认索引即文档

PUT /test3/_doc/1
{
"name":"小白学es",
"age":18,
"bithday":"1997-07-07"
}

查看运行结果

{
"_index" : "test3",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}

插件查看

(2)查看索引,默认配置字段类型!

GET test3

运行结果:

{
"test3" : {
"aliases" : { },
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"bithday" : {
"type" : "date"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"settings" : {
"index" : {
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"
}
}
},
"number_of_shards" : "1",
"provided_name" : "test3",
"creation_date" : "1621064937104",
"number_of_replicas" : "1",
"uuid" : "f_-oPx65RwOk846CysvHRQ",
"version" : {
"created" : "7120199"
}
}
}
}
}

6、扩展,查看集群/索引信息:

查看集群状态:

GET _cat/health

运行结果:

1621065190 07:53:10 elasticsearch yellow 1 1 9 9 0 0 2 0 - 81.8%

查看索引版本信息等:

GET _cat/indices?v

运行结果:

health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green open .kibana_7.12.1_001 aGaAAOZTSQyk_0ZU_lOXsg 1 0 54 23 4.2mb 4.2mb
yellow open test2 3f9X5bcAQXKciY56Il5nfA 1 1 0 0 208b 208b
yellow open test3 f_-oPx65RwOk846CysvHRQ 1 1 1 0 4.2kb 4.2kb
green open .apm-custom-link ZyIwiavFSJSFTbh2cMd8Tg 1 0 0 0 208b 208b
green open .apm-agent-configuration FD1qwkXwTTaCT6orvViPRg 1 0 0 0 208b 208b
green open .kibana_task_manager_7.12.1_001 MIUHf-m7S_e8XrjZMduTpA 1 0 9 272 286.7kb 286.7kb
green open .kibana-event-log-7.12.1-000001 qPBR8ea4Th24CnhfxKa3Sg 1 0 6 0 32.6kb 32.6kb
green open .tasks uwcYsws9QkqK1CXKQiNI0Q 1 0 10 0 50kb 50kb

7、基础测试-修改索引/文档

(1)直接覆盖:PUT

PUT /test3/_doc/1
{
"name":"小白学es2",
"age":18,
"bithday":"1997-07-07"
}

运行结果:version+1,result为updated

{
"_index" : "test3",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}

插件查看结果:

(2)update更新:POST

POST /test3/_doc/1/_update
{
"doc":{
"name":"小白学es3"
}
}

运行结果:version+1,result为updated

#! [types removal] Specifying types in document update requests is deprecated, use the endpoint /{index}/_update/{id} instead.
{
"_index" : "test3",
"_type" : "_doc",
"_id" : "1",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}

插件查看结果:

8、基础测试-删除索引

(1)删除索引

DELETE test1

查看运行结果:

{
"acknowledged" : true
}

(2)删除索引中文档

DELETE test3/_doc/1

查看运行结果:

{
"_index" : "test3",
"_type" : "_doc",
"_id" : "1",
"_version" : 4,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 3,
"_primary_term" : 1
}

六、文档CRUD(增删改查)

1、添加数据:PUT

PUT /xiaobai/user/1
{
"name":"小白",
"age":30,
"desc":"一顿操作猛如虎,一看工资2500",
"tags":["技术宅","直男"]
}

查看运行结果:

#! [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}

插件查看:

同样的方法添加一些数据:

2、获取数据:GET

GET xiaobai/user/1

查看运行结果:

#! [types removal] Specifying types in document get requests is deprecated, use the /{index}/_doc/{id} endpoint instead.
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "小白",
"age" : "30",
"desc" : "一顿操作猛如虎,一看工资2500",
"tags" : [
"技术宅",
"直男"
]
}
}

3、更新数据:PUT/POST

(1)PUT修改:全量字段更新

1号数据name:小白 -> 白神

PUT /xiaobai/user/1
{
"name":"白神",
"age":"30",
"desc":"一顿操作猛如虎,一看工资2500",
"tags":["技术宅","直男"]
}

查看运行结果:

#! [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 2
}

(2)POST _update:指定字段更新(推荐使用)

POST /xiaobai/user/1/_update
{
"doc":{
"name":"小白java"
}
}

查看运行结果:

#! [types removal] Specifying types in document update requests is deprecated, use the endpoint /{index}/_update/{id} instead.
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_version" : 5,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 8,
"_primary_term" : 2
}

4、简单的搜索:GET _searcher

text类型可以根据字段分词搜索,keyword关键词不会处理分词器

GET /xiaobai/user/_search?q=name:小白

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 32,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.9252907,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_score" : 1.9252907,
"_source" : {
"name" : "小白",
"age" : "30",
"desc" : "一顿操作猛如虎,一看工资2500",
"tags" : [
"技术宅",
"直男"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : 0.53899646,
"_source" : {
"name" : "小黑",
"age" : "32",
"desc" : "腹黑男猪脚",
"tags" : [
"旅游",
"渣男",
"游戏宅"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "5",
"_score" : 0.53899646,
"_source" : {
"name" : "小王",
"age" : "32",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男",
"中年危机"
]
}
}
]
}
}

5、复杂操作搜索: _searcher match - 分词模糊匹配

{
"query":{
"match": {
"name": "钻石王老五"
}
}
}

查看运行结果:

{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 4,
"relation": "eq"
},
"max_score": 3.0311832,
"hits": [
{
"_index": "xiaobai",
"_type": "user",
"_id": "6",
"_score": 3.0311832,
"_source": {
"name": "钻石王老五",
"age": "32",
"desc": "社会性死亡",
"tags": [
"技术宅",
"暖男",
"中年危机"
]
}
},
{
"_index": "xiaobai",
"_type": "user",
"_id": "4",
"_score": 1.9277248,
"_source": {
"name": "王五",
"age": "30",
"desc": "正宗青子",
"tags": [
"青年",
"吃货",
"旅游",
"胖子"
]
}
},
{
"_index": "xiaobai",
"_type": "user",
"_id": "7",
"_score": 1.6832076,
"_source": {
"name": "钻石李老四",
"age": "32",
"desc": "社会性死亡",
"tags": [
"技术宅",
"暖男",
"中年危机"
]
}
},
{
"_index": "xiaobai",
"_type": "user",
"_id": "5",
"_score": 1.2623059,
"_source": {
"name": "钻石123",
"age": "32",
"desc": "社会性死亡",
"tags": [
"技术宅",
"暖男",
"中年危机"
]
}
}
]
}
}

6、复杂操作搜索: _searcher match_phrase - 完整模糊匹配

GET /xiaobai/user/_search
{
"query":{
"match_phrase": {
"name": "钻石王老五"
}
}
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 3.0311837,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "6",
"_score" : 3.0311837,
"_source" : {
"name" : "钻石王老五",
"age" : "32",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男",
"中年危机"
]
}
}
]
}
}

7、复杂操作搜索: _searcher term - 完成精确匹配

GET xiaobai/user/_search
{
"query":{
"term": {
"name.keyword": "钻石王老五"
}
}
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.2039728,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : 1.2039728,
"_source" : {
"name" : "钻石王老五",
"age" : "19",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男"
]
}
}
]
}
}

8、复杂操作搜索: _searcher _source - 过滤展示结果

GET /xiaobai/user/_search
{
"query":{
"match_phrase": {
"name": "钻石王老五"
}
},
"_source":["name","desc"]
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 11,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 3.0311837,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "6",
"_score" : 3.0311837,
"_source" : {
"name" : "钻石王老五",
"desc" : "社会性死亡"
}
}
]
}
}

9、复杂操作搜索: _searcher sort - 排序(desc/asc)

GET xiaobai/user/_search
{
"query":{
"match_phrase": {
"name": "钻石"
}
},
"sort":[
{
"age":{
"order":"desc"
}
}
]
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : null,
"_source" : {
"name" : "钻石李老四",
"age" : "32",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男",
"中年危机"
]
},
"sort" : [
32
]
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : null,
"_source" : {
"name" : "钻石123",
"age" : "28",
"desc" : "废物一个",
"tags" : [
"技术宅"
]
},
"sort" : [
28
]
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : null,
"_source" : {
"name" : "钻石王老五",
"age" : "19",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男"
]
},
"sort" : [
19
]
}
]
}
}

10、复杂操作搜索: _searcher from size - 分页查询

GET xiaobai/user/_search
{
"query":{
"match_phrase": {
"name": "钻石"
}
},
"from":0,
"size":2
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 0.77691567,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 0.77691567,
"_source" : {
"name" : "钻石123",
"age" : "28",
"desc" : "废物一个",
"tags" : [
"技术宅"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : 0.62774795,
"_source" : {
"name" : "钻石李老四",
"age" : "32",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男",
"中年危机"
]
}
}
]
}
}

11、复杂操作搜索: _searcher bool - 联合查询 -must - 所有条件均符合

GET xiaobai/user/_search
{
"query":{
"bool": {
"must":[{
"match":{
"name":"钻石王老五"
}
},
{
"match":{
"age":28
}
}
]
}
}
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.7769157,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 1.7769157,
"_source" : {
"name" : "钻石123",
"age" : "28",
"desc" : "废物一个",
"tags" : [
"技术宅"
]
}
}
]
}
}

12、复杂操作搜索:_searcher bool - 联合查询 - should - 满足任意一个条件

GET xiaobai/user/_search
{
"query":{
"bool": {
"should":[{
"match":{
"name":"小白"
}
},
{
"match":{
"age":28
}
}
]
}
}
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 2.9761126,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_score" : 2.9761126,
"_source" : {
"name" : "小白",
"age" : 30,
"desc" : "一顿操作猛如虎,一看工资2500",
"tags" : [
"技术宅",
"直男"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"name" : "钻石123",
"age" : "28",
"desc" : "废物一个",
"tags" : [
"技术宅"
]
}
}
]
}
}

13、复杂操作搜索:_searcher bool - 联合查询 - must_not - 不满足

GET xiaobai/user/_search
{
"query":{
"bool": {
"must_not":[{
"match":{
"name":"小白"
}
},
{
"match":{
"age":28
}
}
]
}
}
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.0,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : 0.0,
"_source" : {
"name" : "钻石李老四",
"age" : "32",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男",
"中年危机"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : 0.0,
"_source" : {
"name" : "钻石王老五",
"age" : "19",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男"
]
}
}
]
}
}

14、复杂操作搜索:_searcher bool - 联合查询 - filter - 过滤

gt(>) gte(>=) lt(<) lte(<=)

GET xiaobai/user/_search
{
"query":{
"bool": {
"must":[{
"match":{
"name":"钻石"
}
}
],"filter":
{"range": {
"age": {
"gte": 10,
"lte": 30
}
}} }
}
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.77691567,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 0.77691567,
"_source" : {
"name" : "钻石123",
"age" : "28",
"desc" : "废物一个",
"tags" : [
"技术宅"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : 0.62774795,
"_source" : {
"name" : "钻石王老五",
"age" : "19",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男"
]
}
}
]
}
}

15、复杂操作搜索:_searcher match - 匹配多个标签分词(空格隔开)

GET xiaobai/user/_search
{
"query":{
"match": {
"tags":"男 技术宅"
}
}
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : 0.6987428,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "1",
"_score" : 0.6987428,
"_source" : {
"name" : "小白",
"age" : 30,
"desc" : "一顿操作猛如虎,一看工资2500",
"tags" : [
"技术宅",
"直男"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : 0.6987428,
"_source" : {
"name" : "钻石王老五",
"age" : "19",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : 0.5337937,
"_source" : {
"name" : "钻石李老四",
"age" : "32",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男",
"中年危机"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 0.38828292,
"_source" : {
"name" : "钻石123",
"age" : "28",
"desc" : "废物一个",
"tags" : [
"技术宅"
]
}
}
]
}
}

16、复杂操作搜索:_searcher bool term - 多个条件精确匹配

GET xiaobai/user/_search
{
"query":{
"bool": {
"should":[{
"term":{
"name":"test01"
}
},
{
"term":{
"name":"test02"
}
}
]}
}
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.8809632,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "4",
"_score" : 1.8809632,
"_source" : {
"name" : "test01",
"age" : "28",
"desc" : "废物一个",
"tags" : [
"技术宅"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "5",
"_score" : 1.8809632,
"_source" : {
"name" : "test02",
"age" : "28",
"desc" : "废物一个",
"tags" : [
"技术宅"
]
}
}
]
}
}

17、复杂操作搜索:_searcher highlight - (自定义高亮显示)

GET xiaobai/user/_search
{
"query":{
"match":{
"name":"钻石"
}
},
"highlight":{
"pre_tags": "<p class='key' style='color:red'>",
"post_tags": "</p>",
"fields": {
"name":{}
}
}
}

查看运行结果:

#! [types removal] Specifying types in search requests is deprecated.
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.3250337,
"hits" : [
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "2",
"_score" : 1.3250337,
"_source" : {
"name" : "钻石李老四",
"age" : "32",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男",
"中年危机"
]
},
"highlight" : {
"name" : [
"<p class='key' style='color:red'>钻</p><p class='key' style='color:red'>石</p>李老四"
]
}
},
{
"_index" : "xiaobai",
"_type" : "user",
"_id" : "3",
"_score" : 1.3250337,
"_source" : {
"name" : "钻石王老五",
"age" : "19",
"desc" : "社会性死亡",
"tags" : [
"技术宅",
"暖男"
]
},
"highlight" : {
"name" : [
"<p class='key' style='color:red'>钻</p><p class='key' style='color:red'>石</p>王老五"
]
}
}
]
}
}

七、Springboot集成es

参考Java REST Client官网文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html

1、原生的依赖与初始化方法

<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.12.1</version>
</dependency>

2、配置基本的项目:

(1)创建sprint-boot module

(2)module选择elasticsearch

(3)查看pom对应的依赖包

(4)调整导入es版本依赖与已本地安装的版本保持一致

pom -> spring-boot-starter-parent -> pring-boot-dependencies -> <elasticsearch.version>7.9.3</elasticsearch.version>

pom中调整为7.12.1,刷新

    <properties>
<java.version>1.8</java.version>
<spring-native.version>0.9.2</spring-native.version>
<!-- 自定义es版本依赖,保证与本地一致 -->
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>

查看后修改成功

(5)构建RestHighLevelClient对象

package com.testbk.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; //找到RestHighLevelClient对象,注入spring中,分析一波源码
@Configuration //xml -bean
public class ElasticSearchClientConfig {
// spring < beans id="restHighLevelClient" class=RestHighLevelClient>
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1",9200,"http")
)
);
return client;
}
}

3、索引API操作

(1)测试创建索引

    //测试索引的创建 Request
@Test
void testCreatIndex() throws IOException {
//1、创建索引请求
CreateIndexRequest request = new CreateIndexRequest("mrwhite_index");
//2、客户端创建请求,indicesClient,请求后获取响应
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse);
}

查看es插件,索引创建成功

(2)测试获取索引 -> 判断索引是否存在

    //测试获取索引
@Test
void testExistIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("mrwhite_index");
boolean exists = client.indices().exists(request,RequestOptions.DEFAULT);
System.out.println(exists);
}

查看运行结果:

true

(3)测试删除索引

    //测试删除索引
@Test
void testDeleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("mrwhite_index");
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}

查看运行结果:同时索引被删除

true

4、文档API操作

(1)测试添加文档

创建用户对象

package com.testbk.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class User {
private String name;
private int age;
}

创建索引并向索引内添加文档

    //测试添加文档
@Test
void testAddDocument() throws IOException {
//创建对象
User user = new User("小白",30);
//创建请求
IndexRequest request = new IndexRequest("mrwhite_index");
//规则 PUT /mrwhite_index/_doc/1
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));
//将我们的数据放入请求json,添加fastjson依赖
request.source(JSON.toJSONString(user), XContentType.JSON);
//客户端发送请求
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
System.out.println(indexResponse.status());
}

查看运行结果:

IndexResponse[index=mrwhite_index,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
CREATED

(2)获取文档,判断是否存在

    //获取文档,判断是否存在 get /index/doc/1
@Test
void testIsExists() throws IOException {
GetRequest getRequest = new GetRequest("mrwhite_index","1");
//不获取返回的_source的上下文
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);
}

查看运行结果:

true

(3)获取文档的信息

    //获取文档的信息
@Test
void testGetDocument() throws IOException {
GetRequest getRequest = new GetRequest("mrwhite_index","1");
GetResponse documentFields = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println(documentFields.getSourceAsString());//打印文档的内容
System.out.println(documentFields);
}

查看运行结果:

{"age":30,"name":"小白"}
{"_index":"mrwhite_index","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"age":30,"name":"小白"}}

(4)更新文档的信息

    //更新文档的信息
@Test
void testUpdateDocument() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("mrwhite_index","1");
updateRequest.timeout("1s");
User user = new User("小白",32);
updateRequest.doc(JSON.toJSONString(user),XContentType.JSON);
UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(updateResponse.status());
}

查看运行结果:OK

(5)删除文档的信息

	//删除文档的信息
@Test
void testDeleteDocument() throws IOException {
DeleteRequest request = new DeleteRequest("mrwhite_inex", "1");
request.timeout("1s");
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
System.out.println(deleteResponse.status());
}

查看运行结果:OK,对应文档被删除掉

(6)批量操作文档

    //批量插入数据
@Test
void testBulkRequest() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
ArrayList<User> userList = new ArrayList<>();
userList.add(new User("xiaobai",15));
userList.add(new User("xiaobai",16));
userList.add(new User("xiaobai",17));
userList.add(new User("xiaobai",18));
userList.add(new User("xiaobai",19));
userList.add(new User("xiaobai",20));
userList.add(new User("xiaobai",21));
for (int i = 0; i <userList.size() ; i++) {
       //id不用的话会随机生成id
bulkRequest.add(new IndexRequest("mrwhite_index").id(""+(i+1)).source(JSON.toJSONString(userList.get(i)),XContentType.JSON));
}
BulkResponse bulkResponse=client.bulk(bulkRequest,RequestOptions.DEFAULT);
System.out.println(bulkResponse.hasFailures()); //打印是否失败,fasle代表成功
}

返回false:

(7)查询文档

    //查询文档
@Test
void testSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest("mrwhite_index");
//构建搜索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//精确匹配
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name","xiaobai");
//匹配所有
//MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAll();
sourceBuilder.query(termQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(searchResponse.getHits()));
for(SearchHit documentFileds:searchResponse.getHits().getHits()){
System.out.println(documentFileds.getSourceAsMap());
}
}

查看运行结果:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":15},"sourceAsString":"{\"age\":15,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":16},"sourceAsString":"{\"age\":16,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":17},"sourceAsString":"{\"age\":17,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":18},"sourceAsString":"{\"age\":18,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"5","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":19},"sourceAsString":"{\"age\":19,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"6","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":20},"sourceAsString":"{\"age\":20,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"7","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":0.06453852,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"xiaobai","age":21},"sourceAsString":"{\"age\":21,\"name\":\"xiaobai\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":0.06453852,"totalHits":{"relation":"EQUAL_TO","value":7}}
{name=xiaobai, age=15}
{name=xiaobai, age=16}
{name=xiaobai, age=17}
{name=xiaobai, age=18}
{name=xiaobai, age=19}
{name=xiaobai, age=20}
{name=xiaobai, age=21}

最新文章

  1. ASP.NET Web API 配置 JSONP
  2. 【zz】MIT牛人解说数学体系
  3. ModernUI教程:处理内容导航事件
  4. ORACLE清除某一字段重复的数据(选取重复数据中另一个字段时期最大值)
  5. BZOJ 2467 生成树
  6. storm概念学习及流处理与批处理的区别
  7. WPS目录制作方法
  8. 【Unity技巧】使用单例模式Singleton
  9. 开涛spring3(3.1) - DI的配置使用
  10. Python内置函数(59)——sorted
  11. MyBatis之分页插件(PageHelper)工作原理
  12. Android MediaCodec的数据处理方式分析
  13. redux 知识点
  14. 关于Unity中的声音管理模块(专题七)
  15. 使用efwplusScript开发Winform程序【像小程序那样开发PC软件】
  16. 音视频处理之FFmpeg+SDL+MFC视频播放器20180411
  17. 经验之道:最有效的iOS内存泄漏检测
  18. 常用 iOS 开源库和第三方组件
  19. CMD (sea.js)模块定义规范
  20. tcpdump学习(1):安装

热门文章

  1. java例题_23 递归求年龄
  2. vue 快速入门 系列 —— 初步认识 vue
  3. (八)Struts2中的参数封装
  4. MySQL实战45讲,丁奇带你搞懂
  5. html页面自定义文字水印效果案例
  6. JavaWeb 补充(XML)
  7. day-7 xctf-level2
  8. Hadoop完整搭建过程(四):完全分布模式(服务器)
  9. 动态扩展磁盘(LVM)
  10. 深入探究ASP.NET Core读取Request.Body的正确方式