1.Lucene创始人Doug Cutting
1985年,Cutting毕业于美国斯坦福大学。他并不是一开始就决心投身IT行业的,在大学时代的头两年,Cutting学习了诸如物理、地理等常规课程。因为学费的压力,Cutting开始意识到,自己必须学习一些更加实用、有趣的技能。这样,一方面可以帮助自己还清贷款,另一方面,也是为自己未来的生活做打算。因为斯坦福大学座落在IT行业的“圣地”硅谷,所以学习软件对年轻人来说是再自然不过的事情了。
Cutting的第一份工作是在Xerox做实习生,Xerox当时的激光扫描仪上运行着三个不同的操作系统,其中的一个操作系统还没有屏幕保护程序。因此,Cutting就开始为这套系统开发屏幕保护程序。由于这套程序是基于系统底层开发的,所以 其他同事可以给这个程序添加不同的主题。这份工作给了Cutting一定的满足感,也是他最早的“平台”级的作品。
尽管Xerox让Cutting积累了不少技术知识,但他却认为,自己当时搞的这些研究只是纸 上谈兵,没有人试验过这些理论的可实践性。于是,他决定勇敢地迈出这一步,让搜索技术可以为更多人所用。
1997年底,Cutting开始以每周两天的时间投入,在家里试着用Java把这个想法变成现实,不久之后,Lucene诞生了。作为第一个提供全文文本搜索的开源函数库,Lucene的伟大自不必多言。之后,Cutting再接再厉,在 Lucene的基础上将开源的思想继续深化。
2004年,Cutting和同为程序员出身的Mike Cafarella决定开发一款可以代替当时的主流搜索产品的开源搜索引擎,这个项目被命名为Nutch。Doug Cutting 希望以开源架构开发出一套搜索技术,类似于现在的 Google Search 或是微软的 Bing,刚好 2004 年 Google Labs 发布了关于自家大数据分析、MapReduce 算法的论文。Doug Cutting 利用 Google 公开的技术扩充他已经开发出来的 Lucene 搜索技术,进而打造出了 Hadoop。
生活中,可能所有人都间接用过他的作品,他是Lucene、Nutch 、Hadoop等项目的发起人。是他,把高深莫测的搜索技术形成产品,贡献给普罗大众;还是他,打造了目前在云计算和大数据领域里如日中天的Hadoop。
2.什么是Elasticsearch
Elasticsearch 是一个分布式的开源搜索和分析引擎,适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。
Elasticsearch 在 Apache Lucene 的基础上开发而成,由 Elasticsearch N.V.(即现在的 Elastic)于 2010 年首次发布。
Elasticsearch 以其简单的 REST 风格 API、分布式特性、速度和可扩展性而闻名,是 Elastic Stack 的核心组件;
Elastic Stack 是适用于数据采集、充实、存储、分析和可视化的一组开源工具。
人们通常将 Elastic Stack 称为 ELK Stack(代指 Elasticsearch、Logstash 和 Kibana),目前 Elastic Stack 包括一系列丰富的轻量型数据采集代理,这些代理统称为 Beats,可用来向 Elasticsearch 发送数据。
传统搜索和实时搜索
传统搜索:从静态数据库中搜索出符合条件的结果,这种结果往往是不可变的、静态的。
实时搜索:搜索的结果是实时变化的。
Lucene、Solr和Elasticsearch的关系
概念不同:
- Lucene是一套信息检索工具包(jar包),并不包含搜索引擎系统,它包含了索引结构、读写索引工具、相关性工具、排序等功能,因此在使用Lucene时仍需要关注搜索引擎系统,例如数据获取、解析、分词等方面的东西。
- Solr是一个有HTTP接口的基于Lucene的查询服务器,封装了很多Lucene细节,自己的应用可以直接利用诸如 .../solr?q=abc 这样的HTTP GET/POST请求去查询,维护修改索引。
- Elasticsearch也是一个建立在全文搜索引擎 Apache Lucene基础上的搜索引擎。采用的策略是分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。
联系:Solr和ES都是基于Lucene实现的!
区别:
- solr利用zookpper进行分布式管理,而elasticsearch自身带有分布式协调管理功能;
- solr比elasticsearch实现更加全面,solr官方提供的工具更多,而elasticsearch本身更注重于核心功能,高级功能多由第三方插件提供;例如图形化界面可以使用Kibana友好支撑;
- solr在传统的搜索应用中表现好于elasticsearch,而elasticsearch在实时搜索应用方面比solr表现好;
- Solr支持更多的数据格式,比如json、xml、csv等,但是ES只支持json格式;
- Solr比较成熟,有一个更成熟的用户、开发者和贡献者社区;ES相对开发维护者较少,更新快,学习使用成本较高,但是将来的一个趋势。
为什么使用Elasticsearch
- Elasticsearch 很快。 由于 Elasticsearch 是在 Lucene 基础上构建而成的,所以在全文本搜索方面表现十分出色。Elasticsearch 同时还是一个近实时的搜索平台,这意味着从文档索引操作到文档变为可搜索状态之间的延时很短,一般只有一秒。因此,Elasticsearch 非常适用于对时间有严苛要求的用例,例如安全分析和基础设施监测。
- Elasticsearch 具有分布式的本质特征。 Elasticsearch 中存储的文档分布在不同的容器中,这些容器称为分片,可以进行复制以提供数据冗余副本,以防发生硬件故障。Elasticsearch 的分布式特性使得它可以扩展至数百台(甚至数千台)服务器,并处理 PB 量级的数据。
- Elasticsearch 包含一系列广泛的功能。 除了速度、可扩展性和弹性等优势以外,Elasticsearch 还有大量强大的内置功能(例如数据汇总和索引生命周期管理),可以方便用户更加高效地存储和搜索数据。
- Elastic Stack 简化了数据采集、可视化和报告过程。 通过与 Beats 和 Logstash 进行集成,用户能够在向 Elasticsearch 中索引数据之前轻松地处理数据。同时,Kibana 不仅可针对 Elasticsearch 数据提供实时可视化,同时还提供 UI 以便用户快速访问应用程序性能监测 (APM)、日志和基础设施指标等数据。
ELK
ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。市面上也被成为Elastic Stack。其中Elasticsearch是一个基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。像类似百度、谷歌这种大数据全文搜索引擎的场景都可以使用Elasticsearch作为底层支持框架,可见Elasticsearch提供的搜索能力确实强大,市面上很多时候我们简称Elasticsearch为es。Logstash是ELK的中央数据流引擎,用于从不同目标(文件/数据存储/MQ)收集的不同格式数据,经过过滤后支持输出到不同目的地(文件/MQ/redis/elasticsearch/kafka等)。Kibana可以将elasticsearch的数据通过友好的页面展示出来,提供实时分析的功能。
市面上很多开发只要提到ELK能够一致说出它是一个日志分析架构技术栈总称,但实际上ELK不仅仅适用于日志分析,它还可以支持其它任何数据分析和收集的场景,日志分析和收集只是更具有代表性。并非唯一性。
3.ES的安装及head插件安装
声明:JDK1.8是最低要求,需要提前安装nodejs、grunt、pathomjs。
npm -v #查看npm版本
node -v #查看node版本
npm install -g grunt -cli #安装grunt
npm install #按照package.json安装所需要的组件放在生成的node_modules文件夹中
windows下安装
-
解压即可;
-
熟悉目录;
bin #启动目录
config #配置文件
log4j2.properties #日志配置文件
jvm.options #java虚拟机相关配置
elasticsearch.yml #ES配置文件,默认端口9200
lib #相关jar包
modules #功能模块
plugins #插件
logs #日志
- 在D:Elasticsearchelasticsearch-7.6.0in路径下使用cmd运行elasticsearch.bat,然后访问端口9200即可。
访问成功的页面:
解决跨域问题
在elasticsearch.yml文件中增加以下配置:
http.cors.enabled: true #启用HTTP端口,允许跨源REST请求。
http.cors.allow-origin: "*" #允许REST请求来自何处。
遇到的问题:
[2020-05-04T12:52:25,721][ERROR][o.e.b.Bootstrap ] [QD-PC] Exception
org.elasticsearch.ElasticsearchException: X-Pack is not supported and Machine Learning is not available for [windows-x86]; you can use the other X-Pack features (unsupported) by setting xpack.ml.enabled: false in elasticsearch.yml
解决方式:在elasticsearch.yml文件中增加以下配置:
xpack.ml.enabled: false
安装head插件
- 下载head插件:https://github.com/mobz/elasticsearch-head,下载zip安装包;
- 解压到ES同级目录下:D:Elasticsearch;
- 在dos窗口进入到head路径下D:Elasticsearchelasticsearch-head-master,使用命令npm install安装相关组件;
- 使用命令npm start启用服务,访问9100端口即可。
访问成功的页面:
4.ES核心概念
4.1 基本概念
ES本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个ES实例。
集群、节点:单个 ES 实例称为一个节点(node)。一组节点构成一个集群(cluster)。默认的集群名称就是elasticsearch。
索引(数据库):索引是含有相同属性的文档集合,索引在ES中是通过一个名字来识别的,必须是英文字母小写,且不含中划线。ES会索引所有字段,经过处理后写入一个倒排索引(Inverted Index)。查找数据的时候,直接查找该索引。
类型(表):一个索引可以定义一个或多个类型,文档必须属于一个类型。
文档(一行):文档是可以被索引的基本数据单位
分片:每个索引都有多个分片,每个分片都是一个lucene索引。分片的好处:分摊索引的搜索压力,分片还支持水平的拓展和拆分以及分布式的操作,可以提高搜索和其他处理的效率。
备份:拷贝一个分片就完成了分片的备份,备份的好处:当主分片失败或者挂掉,备份就可以代替分片进行操作,进而提高了ES的可用性,备份的分片还可以进行搜索操作,以分摊搜索的压力。ES在创建索引时,默认创建5个分片,一份备份,可以修改,分片的数量只能在创建索引的时候指定,索引创建后就不能修改分片的数量了,而备份是可以动态修改的。
ES(面向文档)和关系型数据库(Relation Database RDB)的比较
RDB | ES |
---|---|
数据库(database) | 索引(indices) |
表(table) | 类型(type) |
行(row) | 文档(document) |
列(column) | 字段(field) |
ES(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型包含多个文档(行),每个文档又包含多个字段(列)。
物理设计:ES后台把每个索引划分成多个分片,每个分片可以在集群中的不同服务器间迁移。
逻辑设计:一个索引类型中,包含多个文档,比如文档1,文档2...。当我们索引一篇文档时,可以这样找到它:索引->类型->文档ID,通过这样的方式就能找到具体的文档。注意:ID不必是整数,实际上它是一个字符串。
4.2 正排索引和倒排索引
正排索引:文档ID为key,表中记录每个关键词出现的次数,查找时扫描表中的每个文档中字的信息,直到找到所有包含查询关键字的文档。
倒排索引:
- 由不同的索引词(index term)组成的索引表,称为“词典”(lexicon)。其中包含了各种词汇,以及这些词汇的统计信息(如出现频率nDocs),这些统计信息可以直接用于各种排名算法。
- 由每个索引词出现过的文档集合,以及命中位置等信息构成。也称为“记录表”。就是正排索引产生的那张表。当然这部分可以没有。具体看自己的业务需求了。
正排索引 | 倒排索引 | |
---|---|---|
搜索方式 | 通过key找value | 通过value找key |
优缺点 | 易维护 | 构建索引的时候较为耗时且维护成本较高 |
搜索的耗时太长 | 搜索耗时短 |
ES使用了倒排索引结构,这种结构适用于快速的全文搜索。一个索引由文档中所有不重复的列表组成,对于每一个词,都有一个包含它的文档列表。
5.IK分词器
分词:从一串文本中切分出一个一个的词条,并对每个词条进行标准化。默认的中文分词是把每个字看作一个分词,这显然不符合要求,所以一般使用IK分词器来解决该问题。
IK分词器提供了两种分词算法:ik_smart(最少切分)和ik_max_word(最细粒度划分)。
下载安装
- 下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases,找到和ES一样的版本号下载;
- 安装地址:将安装包解压到ES安装目录的plugins的ik文件夹下;
- 重启ES,访问5601端口即可。
#在ES的bin目录中,使用elasticsearch-plugin可以查看插件
PS D:Elasticsearchelasticsearch-7.6.0in> .elasticsearch-plugin list
future versions of Elasticsearch will require Java 11; your Java version from [C:Program Files (x86)Javajdk1.8.0_181jre] does not meet this requirement
ik
两种算法结果:
# 使用ik_smart
GET _analyze
{
"analyzer":"ik_smart",
"text": "中国子弟兵"
}
运行结果:
{
"tokens" : [
{
"token" : "中国子弟兵",
"start_offset" : 0,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 0
}
]
}
# 使用ik_max_word
GET _analyze
{
"analyzer":"ik_max_word",
"text": "中国子弟兵"
}
运行结果:
{
"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
}
]
}
#对于某些特殊含义的分词,系统自带的词典里面没有收录,需要自己创建字典。
创建自己的字典
- 创建my.dic,加入自己需要的分词;
令狐冲
狂神说
- 在ik分词器的config中修改配置文件IKAnalyzer.cfg.xml,D:Elasticsearchelasticsearch-7.6.0pluginsikconfig.
<?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">my.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords"></entry>
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
然后继续使用kibana查询即可看到字典中的分词了。
6.Rest风格说明
一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。
它主要用于客户端和服务端交互类的软件,基于这个风格设计的软件可以更简洁、更有层次、更易于实现缓存等机制。
基本命令说明:
method | url地址 | 描述 |
---|---|---|
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/索引名称/类型名称/_search | 查询所有数据 |
基础测试
# PUT /索引名/类型名/文档id {请求体}
PUT /kss/type1/1
{
"name":"令狐冲",
"age":3
}
#修改一个文档的两种方式 PUT、POST都可以,但是PUT操作如果某些字段没有修改的话自动修改成空值,POST就比较灵活,可以随意修改一个或者多个字段。
PUT /kss/type1/1
{
"name":"令狐冲1",
"age":18
}
POST /kss/type1/1/_update
{
"doc":{
"name":"令狐冲2",
"age":20
}
}
#删除索引
DELETE kss
PUT kss/user/1
{
"name":"令狐冲",
"age":18,
"desc":["技术宅","分享"]
}
PUT kss/user/2
{
"name":"张三",
"age":3,
"desc":["法外狂徒","渣男"]
}
PUT kss/user/3
{
"name":"李四",
"age":4,
"desc":["靓仔","旅游"]
}
PUT kss/user/3
{
"name":"李五"
}
POST kss/user/3/_update
{
"doc":{
"name":"李五"
}
}
#查询
GET kss/user/_search #查询所有
GET kss/user/_search?q=name:令狐冲 #精准查询
#查询某些字段
GET kss/user/_search
{
"query": {
"match": {
"name": "令" #过滤条件
}
},
"_source":["name","age"] #查询某些字段
}
#排序
GET kss/user/_search
{
"query": {
"match": {
"name": "令"
}
},
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
#分页查询
GET kss/user/_search
{
"query": {
"match": {
"name": "令"
}
},
"from": 0, #从第几条数据开始,数据下标还是从0开始
"size": 3 #返回多少数据
}
#多个条件精确查询
GET kss/user/_search
{
"query": {
"bool": {
"must": [ #must相当于mysql中的and
{
"match": {
"name": "令狐冲"
}
},
{
"match": {
"age": "25"
}
}
]
}
}
}
GET kss/user/_search
{
"query": {
"bool": {
"should": [ #should相当于mysql中的or
{
"match": {
"name": "令狐冲"
}
},
{
"match": {
"age": "25"
}
}
]
}
}
}
GET kss/user/_search
{
"query": {
"bool": {
"must_not": [ #must_not相当于mysql中的not
{
"match": {
"age": "25"
}
}
]
}
}
}
GET kss/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "令狐冲"
}
}
],
"filter": { #filter相当于mysql中的between
"range": {
"age": {
"gte": 10,
"lte": 20
}
}
}
}
}
}
GET kss/user/_search
{
"query": {
"match": {
"desc": "宅 技术 游一游" #多个条件使用空格隔开
}
}
}
GET _cat/indices?v #查看所有索引的状态和内存信息
GET _cat/health #查看ES的状态
精确查询:term查询是直接通过倒排索引指向的词条进行精确查找的。
关于分词:
- term,直接精确查询的;
- match,会使用分词器解析(先分析文档,然后再通过分析的文档进行查询)
两个类型:text(会被分词器解析)和keyword(不会被分词器解析)、
7.集成SpringBoot
-
到相关的依赖,版本一定要和安装的ES版本一致;
-
找到ES官方提供的对象,创建config包,创建配置类来提供对象;
package com.kss.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;
@Configuration
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;
}
}
- 测试。
package com.kss;
import com.alibaba.fastjson.JSON;
import com.kss.pojo.User;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
@SpringBootTest
class kssEsApiApplicationTests {
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient client;
//测试索引的创建
@Test
void textCreateIndex() throws IOException {
//1、创建索引请求
CreateIndexRequest request = new CreateIndexRequest("kss_index");
//2、客户端执行请求 In
CreateIndexResponse createIndexResponse =
client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse);
}
//测试获取索引,判断是否存在这个索引
@Test
void textExistIndex() throws IOException {
GetIndexRequest request =
new GetIndexRequest("kss_index");
boolean exists = client.indices().
exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
//删除索引
@Test
void testDeleteIndex() throws IOException {
DeleteIndexRequest request =
new DeleteIndexRequest("kss_index");
AcknowledgedResponse delete = client.indices().
delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
//测试添加文档
@Test
void testAddDocument() throws IOException {
//创建对象
User user = new User("令狐冲", 3);
//创建请求
IndexRequest request = new IndexRequest("kss_index");
//规则:PUT /kss_index/_doc/1
request.id("1").timeout("1s");
//将数据放入请求 json
request.source(JSON.toJSONString(user), XContentType.JSON);
//客户端发送请求,打印请求结果
IndexResponse index = client.index(request, RequestOptions.DEFAULT);
System.out.println(index.toString());
System.out.println(index.status());
}
//测试文档是否存在
@Test
void testIsExists() throws IOException {
GetRequest getRequest = new GetRequest("kss_index", "1");
//不获取返回时_source的上下文
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);
}
//获得文档的信息
@Test
void testGetDocument() throws IOException {
GetRequest request = new GetRequest("kss_index", "1");
GetResponse getResponse =
client.get(request, RequestOptions.DEFAULT);
System.out.println(getResponse.getSource());
System.out.println(getResponse);
}
//更新文档的信息
@Test
void testUpdateRequest() throws IOException {
UpdateRequest request = new UpdateRequest("kss_index", "1");
request.timeout("1s");
User user = new User("令狐冲学习Java", 18);
request.doc(JSON.toJSONString(user), XContentType.JSON);
UpdateResponse update =
client.update(request, RequestOptions.DEFAULT);
System.out.println(update.status());
}
//删除文档记录
@Test
void testDeleteDocument() throws IOException {
DeleteRequest request = new DeleteRequest("kss_index", "1");
request.timeout("1s");
DeleteResponse delete =
client.delete(request, RequestOptions.DEFAULT);
System.out.println(delete.status());
}
//批量插入数据
@Test
void testBulkRequest() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
ArrayList<User> userArrayList = new ArrayList<>();
userArrayList.add(new User("令狐冲1", 1));
userArrayList.add(new User("令狐冲2", 2));
userArrayList.add(new User("令狐冲3", 3));
userArrayList.add(new User("令狐冲4", 4));
userArrayList.add(new User("令狐冲5", 5));
userArrayList.add(new User("令狐冲6", 6));
for (int i = 0; i < userArrayList.size(); i++) {
bulkRequest.add(new IndexRequest("kss_index")
.id("" + (i + 1))
.source(JSON.toJSONString(userArrayList.get(i)),
XContentType.JSON));
}
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.hasFailures());//是否失败,返回false,代表成功
}
//查询
@Test
void testSearch() throws IOException {
SearchRequest request = new SearchRequest("kss_index");
//构建搜索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.highlighter();
//查询条件,可以使用QueryBuilders工具来构建
//QueryBuilders.termQuery 精确查询
//QueryBuilders.matchAllQuery 匹配所有
// TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "令狐冲");
// sourceBuilder.query(termQueryBuilder);
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
sourceBuilder.query(matchAllQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));//设置超时时间
request.source(sourceBuilder);
SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(searchResponse.getHits()));
System.out.println("-------------------------------------------");
for (SearchHit documentFields:searchResponse.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
}
}