IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> ElasticSearch入门 -> 正文阅读

[大数据]ElasticSearch入门

一、ElasticSearch 简介

中文参考网站https://www.elastic.co/guide/cn/elasticsearch/guide/current/_indexing_employee_documents.html

  • Lucene是一套信息检索工具包! jar包!不包含搜索引擎系统!
  • 包含的∶索引结构!读写索引的工具!排序,搜索规则…工具类!
  • Lucene 和 ElasticSearch 关系︰
    ElasticSearch 是基于Lucene做了一些封装和增强
  • Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。

二、Elasticsearch vs Solr总结

Elasticsearch 和 Solr 都是基于 Lucene 工具包开发的搜索引擎,建议使用 Elasticsearch(数据量大小对效率影响不高,而 Solr 数据量越大效率越低)

  • 1、es基本是开箱即用(解压就可以用!),非常简单。Solr安装略微复杂一丢丢!
  • 2、Solr利用Zookeeper进行分布式管理,而Elasticsearch自身带有分布式协调管理功能。
  • 3、Solr支持更多格式的数据,比如JSON、XML、CSV,而Elasticsearch 仅支持json文件格式。
  • 4、Solr官方提供的功能更多,而Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供,例如图形化界面需要kibana友好支撑~!
  • 5、Solr查询快,但更新索引时慢(即插入删除慢),用于电商等查询多的应用;
    • ES建立索引快(即查询慢),即实时性查询快,用于facebook新浪等搜索。
    • Solr是传统搜索应用的有力解决方案,但Elasticsearch更适用于新兴的实时搜索应用。
  • 6、Solr比较成熟,有一个更大工更成熟的用户、开发和贡献者社区,而Elasticsearch相对开发维护者较少,更新太快,学习使用成本较高。

三、Elasticsearch、head、kibana 安装

1、Elasticsearch 安装

声明:jdk 1.8,最低要求!Elasticsearch 客户端,界面工具

https://www.elastic.co/cn/downloads/elasticsearch
ELK (Elasticsearch、Logstash、Kibana)三剑客,解压即用(web 项目,前端环境)

解压目录
在这里插入图片描述
目录说明

  • bin 启动目录
  • config 配置目录
    • log4j2.properties 日志配置文件
    • jvm.options java 虚拟机配置
    • elasticsearch.yml elasticsearch 配置文件,默认 9200 端口,跨域,集群等
  • lib 相关 jar
  • logs 日志
  • modules 功能模块
  • plugins 插件

启动 ElasticSearch
在这里插入图片描述
http://127.0.0.1:9200/
在这里插入图片描述

2、安装 ES 数据展示插件 head

下载地址
https://github.com/mobz/elasticsearch-head

①、启动
git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm run start
open http://localhost:9100/

npm install 可能会报错,需要升级 npm 版本,如果 phantomjs 不能安装尝试使用如下命令
npm install phantomjs-prebuilt@2.1.14 --ignore-scripts

–ignore-scripts 参数忽略脚本

②、配置跨域

http://127.0.0.1:9100 连接 http://127.0.0.1:9200 存在跨域,需要配置跨域
打开 H:\ElasticSearch\elasticsearch-7.14.0\config\elasticsearch.yml 追加跨域配置

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

连接成功
在这里插入图片描述
新建索引
在这里插入图片描述

3、安装 ES 查询工具 kibana
①、下载启动

下载地址,版本需要和 ElasticSearch 版本一致
https://www.elastic.co/cn/downloads/kibana
kibana 配置
在这里插入图片描述
bin/kibana.bat 启动
在这里插入图片描述

②、访问测试

默认端口 5601 ,http://localhost:5601
在这里插入图片描述
汉化:
修改 kibana-7.14.0-windows-x86_64\config\kibana.yml 文件追加 i18n.locale: "zh-CN"

四、ES 概念

和关系数据库对应关系
在这里插入图片描述

  • NTR:近乎实时的搜索平台。这意味着从索引文档到可搜索之间存在轻微的延迟(通常为一秒)。
  • 集群:集群是一个或多个节点(服务器)的集合,它们共同保存您的整个数据并提供跨所有节点的联合索引和搜索功能。默认有一个集群,名字就是 ElasticSearch
  • 节点:节点是单个服务器,它是集群的一部分,存储您的数据,并参与集群的索引和搜索功能。
  • 索引:就是数据库,索引是具有某些相似特征的文档的集合。
  • 文档:一条条数据,最小的索引搜索单位,就是一个 json 对象,fastjson 进行自动转换
  • 类型:和 mysql 表类似
  • 分片:
    • 它允许您水平拆分/缩放您的内容量
    • 它允许您跨分片(可能在多个节点上)分布和并行化操作,从而提高性能/吞吐量
  • 副本:
    • 它在分片/节点发生故障时提供高可用性。出于这个原因,重要的是要注意副本分片永远不会与复制它的原始/主分片在同一节点上分配。
    • 它允许您扩展搜索量/吞吐量,因为搜索可以在所有副本上并行执行。

五、倒排索引

正排索引:遍历每个文章,找索引对应关系。根据文章找词
倒排索引:根据倒排索引找到与文章的对应关系。根据词找文章
例一
文档1:tom,cat,dog,study up
文档2:cat,study up,sun,red

其中 1 代表存在,0 代表不存在

词组文档1文档2
tom10
cat11
dog10
study up11
sun01
red01

统计如下

项目score
tom文档1
cat文档1,文档2
dog文档1
study up文档1,文档2
sun文档2
red文档2

如果索引某个值,可以很快查找到具体的文章

例二
在这里插入图片描述
简单的倒排索引
在这里插入图片描述
复杂的倒排索引
在这里插入图片描述

  • 单词ID:记录每个单词的单词编号;
  • 单词:对应的单词;
  • 文档频率:代表文档集合中有多少个文档包含某个单词
  • 倒排列表:包含单词ID及其他必要信息
  • DocId:单词出现的文档id
  • TF:单词在某个文档中出现的次数
  • POS:单词在文档中出现的位置

六、IK分词器插件

1、什么是分词器

将一段中文或英文划分成一个个关键字,在搜索时会把信息进行分词,然后与索引库进行对比,默认将中文每个字拆分为一个词,如“我爱吃饭”—》“我”,“爱”,“吃”,“饭”四个词,这显然不符合要求,需要使用中文分词器 IK 解决问题,中文分词建议使用 IK 分词器。
IK 提供了两个分词算法:ik_smart 和 ik_max_word,ik_smart 最少切分, ik_max_word最细粒度切分

2、下载启动

https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.14.0/elasticsearch-analysis-ik-7.14.0.zip

下载完成解压放在ElasticSearch 的plugins 目录下 H:\ElasticSearch\elasticsearch-7.14.0\plugins,

重启 ElasticSearch 可以看到加载了 IK 插件
在这里插入图片描述
也可以使用 elasticsearch-plugin list 看到加载了 ik 插件
在这里插入图片描述

3、开启 ES 安全访问功能

测试出现这个,需要开启安全功能参考https://www.elastic.co/guide/en/elasticsearch/reference/7.14/security-minimal-setup.html说明
在这里插入图片描述

  • elasticsearch.yml 追加 xpack.security.enabled: true
  • 启动 ES ,另开一个cmd,输入 elasticsearch-setup-passwords interactive 自定义密码
  • kibana.yml 追加 elasticsearch.username: “kibana_system”
  • H:\ElasticSearch\kibana-7.14.0-windows-x86_64\bin 目录下,kibana-keystore create 命令新建 kibana-keystore 文件
  • 命令 kibana-keystore add elasticsearch.password 添加密码,输入刚才 ES 中自定义的密码
  • 重启 kibana,访问 http://localhost:5601,用户名 elastic,密码就是自定义的密码
4、测试 IK 分词算法
①、测试 ik 的 ik_smart 最少切分分词算法
GET _analyze
{
  "analyzer": "ik_smart",
  "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" : 4,
      "type" : "CN_WORD",
      "position" : 2
    }
  ]
}
②、测试 ik 的 ik_max_word 最细粒度切分分词算法
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" : 3,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "爱你",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 2
    }
  ]
}

从上面的例子可以看出 IK 两种分词算法,ik_max_word 相比 ik_smart 会有重复的词组,比如 ik_max_word 有 “喜爱“、”爱你”

5、自定义分词器

上面的测试 "我喜爱你"产生的词组没有“喜爱你”,添加一个喜爱你词组

H:\ElasticSearch\elasticsearch-7.14.0\plugins\elasticsearch-analysis-ik-7.14.0\config 目录下新建一个 ye.dic 文件, 其中添加词组 “喜爱你”。注意需要保存文件为 UTF-8
在这里插入图片描述
IK 配置文件配置 ye.dic 自定义词组
H:\ElasticSearch\elasticsearch-7.14.0\plugins\elasticsearch-analysis-ik-7.14.0\config\IKAnalyzer.cfg.xml 配置 ye.dic 文件
<entry key="ext_dict">ye.dic</entry> 其中 key="ext_dict"为扩展词典固定些法,ye.dic 为自定义词组文件名,注意:只能有一个 key=“ext_dict” 的 entry 标签
在这里插入图片描述

6、重启 ES 和 kibana 测试

重启 ES 可以看到加载了 ye.dic 文件
在这里插入图片描述
ik_smart 和 ik_max_word两种算法都正确
在这里插入图片描述

七、ElasticSearch 配置 xpack 之后,ElasticSearch-head连接不上

ElasticSearch 配置 xpack 之后,ElasticSearch-head 连接会出现以下问题,意思就是未授权
在这里插入图片描述
添加 xpack 设置的用户密码http://localhost:9100/?auth_user=elastic&auth_password=..ye123456访问
如果是 Linux crul 访问,可以使用 curl -XGET -uelastic:123456 "http://localhost:9200"
会出现如下问题
在这里插入图片描述
在 H:\ElasticSearch\elasticsearch-7.14.0\config\elasticsearch.yml 文件中追加 http.cors.allow-headers: Authorization,Content-Type
在这里插入图片描述
可以发现连接成功
在这里插入图片描述

八、索引操作

1、数据类型

https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
binary、 boolean、 Keywords、 Numbers、 Dates、 version、 geo_point 等
在这里插入图片描述

2、PUT 创建

7.14 版本不建议指定类型,否则会报警告,请求可以用任意工具发送,不一定适用 kibana

PUT /test/_doc/1 其中 test 为索引名,_doc 为默认类型不用写, 1 为索引 id
在这里插入图片描述
可以看到插入成功
在这里插入图片描述
创建索引格式 (类似建表语句)
在这里插入图片描述
可以看到只有表结构没有数据
在这里插入图片描述

3、GET 获取
GET test2
GET test3/_search

如果 自己的文档没有指定字段类型,则会有默认类型
在这里插入图片描述

4、POST 修改

查询

GET test3/_search
POST test3/_search

修改

POST /test3/_update/2
{
  "doc":{
  "name":"夜猫子",
  "age":20
  }
}

# 不能算是真正的修改,应该算是覆盖
# 保证索引名称/索引类型/索引id 存在就是修改,否则是新建 
PUT /test3/_doc/2
{
  "name":"夜猫子",
  "age":18,
  "birthday":"2020-1-8"
}

其中 _version 表示修改的次数,result:”update“ 代表修改
在这里插入图片描述

5、DELETE 删除
# 删除整个test2索引
DELETE test2
# 删除 test3 索引 中 id = 3的文档记录
DELETE test3/_doc/3

在这里插入图片描述
在这里插入图片描述

九、文档操作

文档的操作同索引一样,也是通过 resultful 风格接口增删改查
在这里插入图片描述

带参数查询

GET /test3/_doc/_search?q=name:叶
在这里插入图片描述

  • _score,max_score 可以用来判断谁更符合
  • hits 查询出来的具体文档
1、结果过滤、排序

索引数据如下,注意:排序之后 _score 为 null,不存在权重
在这里插入图片描述

  • 结果过滤 ----> 指定查询字段,select * 和 select id,name 区别
  • 排序 -----> desc 降序,asc 升序
    在这里插入图片描述
2、分页查询
GET /test3/_search
{
  "query":{
    "match": {
      "birthday":"2020"
     }
    },
    "_source": ["name","age","height"],
    "sort": [
      {
        "age": {
          "order": "asc"
        },
        "height": {
          "order": "desc"
        }
      }
    ],
    "from": 0, # 从第0个开始
    "size": 2	# 查询两个
}
3、多条件查询

注意:match 模糊查询,只支持字符串,数字等格式不支持

  • bool:条件查询
  • must:条件都要满足,类似 a and b , a&&b
  • must_not:条件都不满足 !(a&&b)
  • should:满足其已即可 a or b , a || b
    在这里插入图片描述
4、范围查询过滤器 filter

gt >,gte >=,lt <,lte <=
查询 name 包含 “叶” 或者 age = 28 并且过滤 age >=10 && age<=20
在这里插入图片描述

5、filed 多值查询–in

查询 habbit 的多个值,类似 mysql in 加模糊匹配操作
在这里插入图片描述

6、精准查询 term
  • text --------> text 类型字段,默认分词,term 会从分词器中查询,如果没有则为空注意不是模糊查询,精准匹配分词器分词结果

  • 在这里插入图片描述

  • keyword -------> keyword 类型字段,keyword 不会分词,该类型字段为一个字符串

  • 在这里插入图片描述

keyword 就是一个字符串,没有被拆分,当你使用 match 是会不用到分词器,所以不支持模糊匹配
在这里插入图片描述

①、term 查询 text 类型字段,如果精准查询失败,原因事经过分词器,默认分为一个字一个词 这里是引用
②、term 查询 text 类型字段,经过分词器,找到 java 对应的词组 在这里插入图片描述
③、term 查询 keyword 类型字段,keyword 不分词,只支持精准查询 在这里插入图片描述
④、term 查询 keyword 类型字段,keyword 不分词,只支持精准查询,查询成功 在这里插入图片描述

term 查询多个值和 match 类似
在这里插入图片描述

7、match 和 term 区别
  • match 查询: text 字段支持模糊查询以及精准匹配,keyword 只支持精准匹配
  • trem 查询: text 字段支持分词器分词结果的精准匹配,keyword 只支持精准匹配
8、高亮查询
①、查询高亮

高亮会默认添加 标签
在这里插入图片描述

②、自定义高亮标签

自定义高亮字段前缀后缀
在这里插入图片描述

十、springboot 集成

1、ES api 简单测试

官方文档,使用 Java REST Client [7.14]
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-getting-started-initialization.html

①、导入依赖
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
		</dependency>

指定版本 elasticsearch 集成版本,尽量修改为本地 elasticsearch 版本,pom文件中指定版本,覆盖项目版本

	<properties>
		<java.version>1.8</java.version>
		<elasticsearch.version>7.14.0</elasticsearch.version>
	</properties>

在这里插入图片描述

②、yml 配置 ElasticSearch

如果是集群可以配置多个服务器
Java代码配置

@Configuration
public class ElasticSearchClientConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestClientBuilder restClientBuilder = RestClient.builder(
                new HttpHost("localhost", 9200, "http")
                //new HttpHost("localhost", 9201, "http")
    );
        return new RestHighLevelClient(restClientBuilder);
    }
}

yml 配置

spring:
  elasticsearch:
    rest:
      uris: http://127.0.0.1:9200
      username: elastic
      password: ..ye123456
2、索引的增删改查
	@Autowired
	RestHighLevelClient restHighLevelClient;
	// 创建索引请求 Request
	@Test
	void createIndex() throws IOException {
		// 创建索引请求
		CreateIndexRequest createIndexRequest = new CreateIndexRequest("test_es_api");
		// 客户端执行请求 indices,请求后获得响应
		CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
		System.out.println(createIndexResponse);
	}
	// 测试获取索引
	@Test
	void existIndex() throws IOException {
		GetIndexRequest getIndexRequest = new GetIndexRequest("test_es_api");
		boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
		System.out.println(exists);
	}
	// 删除索引
	@Test
	void deleteIndex() throws IOException {
		DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("test_es_api");
		AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
		System.out.println(delete);
	}
3、文档增删改查
①、单文档CRUD
	// 添加文档 put /test_user/_doc/1
	@Test
	void addDoc() throws IOException {
		User user = new User("小林子", 25);
		IndexRequest indexRequest = new IndexRequest("test_user");
		indexRequest.id("1");
		indexRequest.timeout("1s");
		String s = JSON.toJSONString(user);
		// 将数据放入请求
		indexRequest.source(s, XContentType.JSON);
		// 客户端发送请求,返回响应结果
		IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
		// 添加 CREATE
		System.out.println(indexResponse.status());
		System.out.println(indexResponse);
	}
	// 获取文档,判断文档是否存在 get /test_user/_doc/1
	@Test
	void exitsDoc() throws IOException {
		GetRequest getRequest = new GetRequest("test_user","1");
		boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
		System.out.println(exists);
	}
	// 获取文档信息 get /test_user/_doc/1
	@Test
	void getDocData() throws IOException {
		GetRequest getRequest = new GetRequest("test_user", "1");
		GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
		// 获取 source,存入的完整对象
		Map<String, Object> source = getResponse.getSource();
		System.out.println(source.get("name")); // 小林子
		System.out.println(source.get("age")); // 25
		// 默认 1,修改会加一
		System.out.println(getResponse.getVersion());
		//打印 Source    {"age":25,"name":"小林子"}
		System.out.println(getResponse.getSourceAsString());
		// 打印全部内容,和命令行返回结果相同  {"_index":"test_user","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"age":25,"name":"小林子"}}
		System.out.println(getResponse);
	}

	// 更新文档信息 post /test_user/_update/1
	@Test
	void updateDocData() throws IOException {
		UpdateRequest updateRequest = new UpdateRequest("test_user","1");
		updateRequest.timeout("1s");
		HashMap<String, Object> stringObjectHashMap = new HashMap<>();
		stringObjectHashMap.put("name","叶灵芸");
		stringObjectHashMap.put("age",89);
		updateRequest.doc(stringObjectHashMap);
		UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
		// 成功 OK,id 不存在 NOT_FOUND
		System.out.println(updateResponse.status());
		// UpdateResponse[index=test_user,type=_doc,id=1,version=2,seqNo=1,primaryTerm=1,result=updated,shards=ShardInfo{total=2, successful=1, failures=[]}]
		System.out.println(updateResponse);
	}

	// 删除 delete /test_user/_doc/2
	@Test
	void deleteDocData() throws IOException {
		DeleteRequest test_user = new DeleteRequest("test_user", "5");
		DeleteResponse delete = restHighLevelClient.delete(test_user, RequestOptions.DEFAULT);
		// 成功 OK,id 不存在 NOT_FOUND
		System.out.println(delete.status());
		// DeleteResponse[index=test_user,type=_doc,id=2,version=2,result=deleted,shards=ShardInfo{total=2, successful=1, failures=[]}]
		System.out.println(delete);
	}
②、批量文档CRUD

批量删除、更新类似,只需要修改 for 循环中,new IndexRequest()、new DeleteRequest、new UpdateRequest()

	// 批量插入数据
	@Test
	void testBulk() throws IOException {
		BulkRequest bulkRequest = new BulkRequest();

		ArrayList<User> users = new ArrayList<>();
		users.add(new User("张三",56));
		users.add(new User("李四",23));
		users.add(new User("王五",99));
		users.add(new User("张麻子",33));
		for (User user : users) {
			// 不指定 id ,默认生成 id ,如 lxUuh3sB4XNJgblKGvMz、lhUuh3sB4XNJgblKGvMz
			bulkRequest.add(new IndexRequest("test_user").id("").source(JSON.toJSONString(user),XContentType.JSON).timeout("1s"));
		}
		BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
		// OK
		System.out.println(bulkResponse.status());
		// 是否失败
		System.out.println(bulkResponse.hasFailures());
		System.out.println(bulkResponse);
	}
	
	// 批量删除数据
	@Test
	void testBulkDelete() throws IOException {
		BulkRequest bulkRequest = new BulkRequest();
		String[] strings = new String[]{"lxUuh3sB4XNJgblKGvMz","lhUuh3sB4XNJgblKGvMz","lxUuh3sB4XNJgblKGvMz"};
		for (String string : strings) {
			bulkRequest.add(new DeleteRequest("test_user",string).timeout("1s"));
		}
		BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
		System.out.println(bulk.hasFailures());
		System.out.println(bulk);
	}
4、高级查询

测试表数据
在这里插入图片描述

①、模糊查询、多值查询、结果筛选指定字段

kibana 方式,term不支持多值查询
在这里插入图片描述

代码实现

 	@Test
    void searchData() throws IOException {
        SearchRequest searchRequest = new SearchRequest("test_student");
        // 构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 查询条件可以使用 QueryBuilders 构建
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "1 2 5");
        searchSourceBuilder.query(queryBuilder);
        // 指定结果集字段,第一个参数指定包含哪些字段,第二个字段指定排除哪些字段
        searchSourceBuilder.fetchSource(new String[]{"name","birth"},new String[]{"age"});
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : searchResponse.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

结果
在这里插入图片描述

②、高亮查询

kibana 调用
在这里插入图片描述
java 代码实现

    // 高亮查询
    @Test
    void testHighLight() throws IOException {
        SearchRequest searchRequest = new SearchRequest("test_student");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 构造搜索
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "1 2 5");
        searchSourceBuilder.query(matchQueryBuilder);
        // 构造高亮显示
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        // 指定高亮字段
        highlightBuilder.field("name");
        // 指定高亮字段前后缀
        highlightBuilder.preTags("<p class='key' style='color:red'>");
        highlightBuilder.postTags("</p>");
        searchSourceBuilder.highlighter(highlightBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : searchResponse.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
            System.out.println(hit.getHighlightFields());
        }
    }

结果
在这里插入图片描述

③、多字段查询

kibana 接口
在这里插入图片描述
代码实现

    // 多字段查询
    @Test
    void testManyFiled() throws IOException {
        SearchRequest searchRequest = new SearchRequest("test_student");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "1 2 5");
        MatchQueryBuilder queryBuilder2 = QueryBuilders.matchQuery("age", "30");
        // must、should
        searchSourceBuilder.query(QueryBuilders.boolQuery().must(queryBuilder).must(queryBuilder2));
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(search.getHits().getHits()[0].getSourceAsMap());
    }
④、排序、分页

在这里插入图片描述

kibana 接口
在这里插入图片描述
Java代码实现

  @Test
    void testOrder() throws IOException {
        SearchRequest searchRequest = new SearchRequest("test_student");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 查询条件
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "小");
        searchSourceBuilder.query(matchQueryBuilder);
        // 排序条件
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("age");
        fieldSortBuilder.order(SortOrder.DESC); // 降序
        FieldSortBuilder fieldSortBuilder2 = SortBuilders.fieldSort("height");
        fieldSortBuilder2.order(SortOrder.ASC); // 升序
        searchSourceBuilder.sort(Arrays.asList(fieldSortBuilder,fieldSortBuilder2));
        // 添加分页 从第 0 条开始, 3 个长度
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(3);
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

结果
在这里插入图片描述

十一、总结 Java 写法

  • 根据 kibana API 接口实现Java代码
    • GET /test/_search ------> new SearchRequest()
    • POST /test/_update/2 ----------> new UpdateRequest()
    • API 请求里写的参数,根据层级关系在代码实现请求参数和获取想要的结果
    • 相同层级之间可以使用链式编程
    • 从最外层一层一层解析请求编写 Java 代码
    • 条件构建器,query 对应 QueryBuilders 工具方法,sort 对应 SortBuilders 工具方法

数据表
在这里插入图片描述

下面请求多字段查询,分页、排序高亮、多条件,结果过滤

GET /test_student/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"name": "小" }},
        {"match": {"address": "西" }}
      ],
      "filter": [
        {"range": {
          "height": {"gte": 150,"lte": 200}
        }},
         {"range": {
          "age": {"gt": 15,"lt": 35}
        }}
      ]
    }
  },
  "sort": [
    { "age": {"order": "desc"}},
    {"height": { "order": "asc"}}
  ],
  "highlight": {
    "pre_tags":"<a>",
    "post_tags":"</a>", 
    "fields": {
      "name": {},
      "address": {}
    }
  }, 
  "_source": ["name","name","address","height","birth"], 
  "from": 0,
  "size": 4
}

代码实现

    @Test
    void testOrder() throws IOException {
        // 建立查询请求
        SearchRequest searchRequest = new SearchRequest("test_student");

        // 构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // query 查询条件部分
        // query.bool.must 部分
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "小");
        MatchQueryBuilder matchQueryBuilder2 = QueryBuilders.matchQuery("address", "西");
        // query.bool.filter 部分
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");
        rangeQueryBuilder.gte(15);
        rangeQueryBuilder.lte(35);
        RangeQueryBuilder rangeQueryBuilder2 = QueryBuilders.rangeQuery("height");
        rangeQueryBuilder.gte("150");
        rangeQueryBuilder.lte("200");
        // 以下三步可以使用链式编程
        //         searchSourceBuilder.query(QueryBuilders.boolQuery().must(matchQueryBuilder).must(matchQueryBuilder1).filter(rangeQueryBuilder).filter(rangeQueryBuilder1));
        // ①、添加条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(matchQueryBuilder).must(matchQueryBuilder2);
        // ②、添加过滤
        BoolQueryBuilder boolQueryBuilder1 = boolQueryBuilder.filter(rangeQueryBuilder).filter(rangeQueryBuilder1);
        // ③、构建查询添加查询条件
        searchSourceBuilder.query(boolQueryBuilder1);

        // sort 排序部分
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("age");
        fieldSortBuilder.order(SortOrder.DESC); // 倒序 大 ---> 小
        FieldSortBuilder fieldSortBuilder2 = SortBuilders.fieldSort("height");
        fieldSortBuilder2.order(SortOrder.ASC); // 正序 小 -----> 大
        // 构建中添加排序
        searchSourceBuilder.sort(Arrays.asList(fieldSortBuilder,fieldSortBuilder2));

        // 分页部分
        searchSourceBuilder.from(0); // 从查询结果中第 0 条开始
        searchSourceBuilder.size(3); // 总共返回三条

        // 高亮显示
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<a>"); // 前缀
        highlightBuilder.postTags("</a>"); // 后缀
        highlightBuilder.field("name").field("address");;  // 高亮字段
        // 构建中添加高亮
        searchSourceBuilder.highlighter(highlightBuilder);

        // _source 部分,筛选结果集需要展示的字段
        searchSourceBuilder.fetchSource(new String[]{"name","address","age","height","birth"},new String[]{});

        // 将 source 通过 searchSourceBuilder 条件过滤,从结果集可以看出,_source 就是表数据,没有其他字段
        searchRequest.source(searchSourceBuilder);
        // 使用客户端通过请求索引
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 获取返回结果,可以使用对象的方式去除想要的值
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
            System.out.println(hit.getHighlightFields());
        }
    }

结果
在这里插入图片描述

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-08-31 15:30:56  更:2021-08-31 15:32:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 17:00:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码