上一篇文章:跟乐乐学ES!(三)ElasticSearch 批量操作与高级查询
准备数据
一.创建招聘信息结构化索引
# put:127.0.0.1:9200/recruitment
{
"settings":{
"index":{
"number_of_shards":"5",
"number_of_replicas":"0"
}
},
"mappings":{
"properties":{
"id":{ #id
"type":"integer"
},
"name":{ #姓名
"type":"keyword"
},
"sex":{ #性别
"type":"boolean"
},
"tele":{ #电话
"type":"long"
},
"address":{ #地址
"type":"keyword"
},
"technology":{ #技能 使用ik中文分词器定义该字段为中文分词字段。
"type":"text",
"analyzer":"ik_max_word"
}
}
}
}
二.添加文档数据
post:127.0.0.1:9200/recruitment/_bulk
{"index":{"_index":"recruitment","_type":"_doc"}}
{"id":"1","name":"杜神","sex":true,"tele":13000000000,"address":"北京市朝阳区","technology":"全栈 - javaEE开发,C#开发,JavaScript,Vue,ElementUi"}
{"index":{"_index":"recruitment","_type":"_doc"}}
{"id":"2","name":"小明","sex":true,"tele":18600000001,"address":"南京市玄武区","technology":"全栈 - javaEE开发,C#开发,Bootstarp,Beetl,nodejs"}
{"index":{"_index":"recruitment","_type":"_doc"}}
{"id":"3","name":"李京","sex":false,"tele":15000000000,"address":"洛阳市涧西区","technology":"前端 - javaScript,Jquery,nodeJs,vue,ElementUi,Beetl,Css,Html,El表达式,Jsp"}
{"index":{"_index":"recruitment","_type":"_doc"}}
{"id":"4","name":"王斌","sex":true,"tele":17100000000,"address":"淄博市张店区","technology":"java后端 - BeetlSql,高并发,分布式架构,SpringBatch,SpringBoot,SrpingCloud,Dubbo,Zookeeper,Ssm,Mysql,ElasticSearch"}
{"index":{"_index":"recruitment","_type":"_doc"}}
{"id":"5","name":"许昱航","sex":true,"tele":15500000000,"address":"郑州市金水区","technology":"java后端 - Mysql,MongoDb,Redis,Beetlsql,Mybatis,MybatisPlus,SpringDataJpa,ElasticSearch,Spring"}
{"index":{"_index":"recruitment","_type":"_doc"}}
{"id":"6","name":"刘佳佳","sex":false,"tele":13500000000,"address":"北京市东城区","technology":"java后端 - springcloud,springboot,Redis,Mysql,MongoDb,ElasticSearch,Mybatis"}
ElasticSearch的客户端种类介绍
Java中存在两个类型的ElasticSearch客户端,分别为Rest风格客户端(基于http访问)和JavaApi客户端。
乐乐本期讲解的是Rest风格的客户端使用。
而Rest风格的客户端呢,又分为两种,
一种是低级客户端 Java Low Level REST Client,
该客户端通过http来访问ElasticSearch服务器集群,在请求时,需要手动将数据进行封装,然后转换为JSON来发送请求给ElasticSearch。对于ElasticSearch响应回来的JSON,也需要手动封装为对象来查看。缺点是需要将数据在对象和JSON间手动转换,优点是兼容所有的ElasticSearch版本。
另一种是高级客户端 Java High Level REST Client。
高级客户端是基于低级客户端的实现,它提供了很多便捷的Api来替代手动封装数据和转换JSON这一步骤。
低级客户端使用
引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.elasticsearchdemo</groupId>
<artifactId>ElasticSearch-Demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ElasticSearchDemo</name>
<description>Spring-BootTest</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- start 引入ElasticSearch依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- end 引入ElasticSearch依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建搜索语法实体类
在ElasticSearch中,我们通过语法Query,match,filter等来进行查询,他们最终会组成一个json结构,我们要用这些json请求Es后台。
在通过PostMan来请求时,我们是动手敲。但在我们通过Java进行查询时,如果还是手敲json结构的字符串,那么将会很费时间。
因此我们可以创建好对应的实体类来封装查询语法,届时直接序列化为json。
这里我仅仅用match语法来完成分词搜索,所以仅仅创建Query和Match这两个语法实体。
需要注意的是,具体的查询语句则是用Map对象来封装。
package com.elasticsearchdemo.pojo.query;
/**
* 本实体类对应于ElasticSearch查询语法中'Query'的Json结构
*/
public class QueryForJsonOfElasticSearch {
private Object query;
public Object getQuery() {
return query;
}
public void setQuery(Object query) {
this.query = query;
}
public QueryForJsonOfElasticSearch(Object query) {
super();
this.query = query;
}
}
package com.elasticsearchdemo.pojo.query;
/**
* 本实体类对应于ElasticSearch查询语法中'match'的Json结构
*/
public class MatchForJsonOfElasticSearch{
private Object match;
public Object getMatch() {
return match;
}
public void setMatch(Object match) {
this.match = match;
}
public MatchForJsonOfElasticSearch(Object match) {
super();
this.match = match;
}
}
编写搜索业务逻辑
package com.elasticsearchdemo.controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpHost;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Node;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.elasticsearchdemo.pojo.query.MatchForJsonOfElasticSearch;
import com.elasticsearchdemo.pojo.query.QueryForJsonOfElasticSearch;
import com.fasterxml.jackson.databind.ObjectMapper;
@RestController
@RequestMapping("/es")
public class ElasticSearchController {
private RestClient restClient;
{
System.out.println("es初始化。。。。。");
RestClientBuilder rcb = RestClient.builder(new HttpHost("127.0.0.1", 9200, "http"));
rcb.setFailureListener(new RestClient.FailureListener() {
@Override
public void onFailure(Node node) {
System.out.println("ElasticSearch初始化报错:" + node);
}
});
this.restClient = rcb.build();
}
/**
* 全文搜索 之 多词搜索
*
* @param index 索引
* @param field 要搜索的字段
* @param param 搜索的关键字
* @return
*/
@GetMapping("/query/{index}/{field}/{param}")
public Object multiWordSearch(@PathVariable("index") String index, @PathVariable("field") String field,
@PathVariable("param") String param) throws IOException {
// 包路径为 org.elasticsearch.client.Request;
// 在7.x以上的ElasitcSearch服务器版本中,类型名默认为'_doc',如果不指定类型名而仅仅指定索引名,那么默认搜索'_doc'类型下的文档。
Request requestObj = new Request("post", "/" + index + "/_search");// 等于
// post方式请求:http://localhost:9200/索引名/_search
/*
* //添加参数 requestObj.addParameter("pretty", "true");// 等于
* http://localhost:9200/索引名/_search?pretty
*/
// 通过Map来封装具体的查询语法实体类。
Map<String, Object> queryData = new HashMap<String, Object>();
queryData.put(field, param);// field=technology,param=java c#
// Json请求结构封装,此处行代表的是Match语法实体对象传入具体的查询语句对象'queryData',Query语法实体对象再传入Match语法实体对象,
QueryForJsonOfElasticSearch queryForJsonOfElasticSearchObj = new QueryForJsonOfElasticSearch(
new MatchForJsonOfElasticSearch(queryData));
// 通过Jackson的ObjectMapper对象可以实体类进行序列化处理。
ObjectMapper om = new ObjectMapper();
// 通过writerValueAsString方法将实体类序列化
String writeValueAsString = om.writeValueAsString(queryForJsonOfElasticSearchObj);
System.out.println(writeValueAsString + "\n");
// 将序列化后的json字符串通过setJsonEntity方法交给Request请求对象,作为请求数据体
requestObj.setJsonEntity(writeValueAsString);
// 将Request请求对象交给RestClient对象的performRequest方法,来正式发起请求,随之返回对象Response,我们可以通过Reseponse响应对象来查看响应状态和搜索结果
Response responseObj = this.restClient.performRequest(requestObj);
// Reponse响应对象的getStatusLine能获取响应状态,如:HTTP/1.1 200 OK
System.out.println(responseObj.getStatusLine());
// Reponse响应对象的getEntity()方法用来获取响应的搜索结果。
return EntityUtils.toString(responseObj.getEntity());
}
/**
* 根据id来搜索
* @param index 索引名
* @param id id
* @return
*/
@GetMapping("/queryById/{index}/{id}")
public Object byIdSearch(@PathVariable("index") String index,@PathVariable("id") String id) throws IOException{
// 此处默认类型名为'_doc'
Request requestObj = new Request("get", "/"+index+"/_doc/"+id);
// 将Request请求对象交给RestClient对象的performRequest方法,来正式发起请求,随之返回对象Response,我们可以通过Reseponse响应对象来查看响应状态和搜索结果
Response responseObj = this.restClient.performRequest(requestObj);
System.out.println(responseObj.getStatusLine());
// Reponse响应对象的getEntity()方法用来获取响应的搜索结果。
return EntityUtils.toString(responseObj.getEntity());
}
}
因为太长,我们拆段来讲解。
首先是第一部分:
定义RestClient对象的成员变量,采用静态代码块来初始化Es的Rest风格低级客户端。
private RestClient restClient;
{
System.out.println("es初始化。。。。。");
RestClientBuilder rcb = RestClient.builder(new HttpHost("127.0.0.1", 9200, "http"));
rcb.setFailureListener(new RestClient.FailureListener() {
@Override
public void onFailure(Node node) {
System.out.println("ElasticSearch初始化报错:" + node);
}
});
this.restClient = rcb.build();
}
接着是第二部分:
/**
* 全文搜索 之 多词搜索
*
* @param index 索引
* @param field 要搜索的字段
* @param param 搜索的关键字
* @return
*/
@GetMapping("/query/{index}/{field}/{param}")
public Object multiWordSearch(@PathVariable("index") String index, @PathVariable("field") String field,
@PathVariable("param") String param) throws IOException {
// 包路径为 org.elasticsearch.client.Request;
// 在7.x以上的ElasitcSearch服务器版本中,类型名默认为'_doc',如果不指定类型名而仅仅指定索引名,那么默认搜索'_doc'类型下的文档。
Request requestObj = new Request("post", "/" + index + "/_search");// 等于
// post方式请求:http://localhost:9200/索引名/_search
/*
* //添加参数 requestObj.addParameter("pretty", "true");// 等于
* http://localhost:9200/索引名/_search?pretty
*/
// 通过Map来封装具体的查询语法实体类。
Map<String, Object> queryData = new HashMap<String, Object>();
queryData.put(field, param);// field=technology,param=java c#
// Json请求结构封装,此处行代表的是Match语法实体对象传入具体的查询语句对象'queryData',Query语法实体对象再传入Match语法实体对象,
QueryForJsonOfElasticSearch queryForJsonOfElasticSearchObj = new QueryForJsonOfElasticSearch(
new MatchForJsonOfElasticSearch(queryData));
// 通过Jackson的ObjectMapper对象可以实体类进行序列化处理。
ObjectMapper om = new ObjectMapper();
// 通过writerValueAsString方法将实体类序列化
String writeValueAsString = om.writeValueAsString(queryForJsonOfElasticSearchObj);
System.out.println(writeValueAsString + "\n");
// 将序列化后的json字符串通过setJsonEntity方法交给Request请求对象,作为请求数据体
requestObj.setJsonEntity(writeValueAsString);
// 将Request请求对象交给RestClient对象的performRequest方法,来正式发起请求,随之返回对象Response,我们可以通过Reseponse响应对象来查看响应状态和搜索结果
Response responseObj = this.restClient.performRequest(requestObj);
// Reponse响应对象的getStatusLine能获取响应状态,如:HTTP/1.1 200 OK
System.out.println(responseObj.getStatusLine());
// Reponse响应对象的getEntity()方法用来获取响应的搜索结果。
return EntityUtils.toString(responseObj.getEntity());
}
此方法用于全文搜索中的分词搜索,对应到下面的这个PostMan手动查询方式
其次为第三部分:
/**
* 根据id来搜索
* @param index 索引名
* @param id id
* @return
*/
@GetMapping("/queryById/{index}/{id}")
public Object byIdSearch(@PathVariable("index") String index,@PathVariable("id") String id) throws IOException{
// 此处默认类型名为'_doc'
Request requestObj = new Request("get", "/"+index+"/_doc/"+id);// index=recruitment,id=RPuuF3kBhcx63ZgbAOA8
// 将Request请求对象交给RestClient对象的performRequest方法,来正式发起请求,随之返回对象Response,我们可以通过Reseponse响应对象来查看响应状态和搜索结果
Response responseObj = this.restClient.performRequest(requestObj);
System.out.println(responseObj.getStatusLine());
// Reponse响应对象的getEntity()方法用来获取响应的搜索结果。
return EntityUtils.toString(responseObj.getEntity());
}
此方法应用于根据id搜索,对应于下图的使用PostMan手动查询方式
以上两个方法仅用于参考,实际开发业务中,所要用到的语法关键字很多,需要封装较为复杂的语法查询实体类。
高级客户端使用
ElasticSearch高级客户端的官方Api文档在这里:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.2/java-rest-high-getting-started.html
高级客户端中,
高级搜索(以json形式发起post请求的搜索)需要用到SearchRequest对象。
普通搜索(以get形式发起get请求的搜索)需要用到GetRequest对象。
删除操作需要用到DeleteRequest对象。
添加文档操作需要用到IndexRequest对象。
更新(覆盖)操作需要用到UpdateRequest对象。
同步操作和异步操作的区别
ES尽管相对于关系型数据库的查询速度要快,但我们搜索某个索引下的数据时还是要耗费一定的时间的。
假如我们调用一个同步式的搜索方法,那么需要先执行A查询,并只有等待A查询出结果后,才能等待B查询。
但是如果使用异步的话,我们可以执行A查询,并在A查询响应出结果前就执行B查询。
同步/异步增删改方法名区别
在实际的使用上,异步操作和同步操作的区别,仅限于高级客户端RestHighLevelClient的正式请求方法不同而已。
高级搜索:
RestHighLevelClient.searchAsync(); 异步
RestHighLevelClient.search(); 同步
判断是否存在:
RestHighLevelClient.existsAsync(); 异步
RestHighLevelClient.exists(); 同步
指定id搜索:
RestHighLevelClient.getAsync(); 异步
RestHighLevelClient.get(); 同步
添加操作:
RestHighLevelClient.indexAsync(); 异步
RestHighLevelClient.index(); 同步
更新操作:
RestHighLevelClient.updateAsync(); 异步
RestHighLevelClient.update(); 同步
删除操作:
RestHighLevelClient.deleteAsync(); 异步
RestHighLevelClient.delete(); 同步
同步操作增删改示例
package com.elasticsearchdemo.controller;
import org.apache.http.HttpHost;
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.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.Operator;
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.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/eslevel")
public class ElasticSearchLevelClientController {
//高级客户端对象为RestHighLevelClient
private RestHighLevelClient restHighLevelClientObj;
//通过静态代码块初始化高级客户端。
{
//建立连接,填写es地址和端口,以及请求形式
RestClientBuilder restClientBuilderObj = RestClient.builder(new HttpHost("127.0.0.1",9200,"http"));
//将连接对象赋值给高级客户端对象的构造。
this.restHighLevelClientObj = new RestHighLevelClient(restClientBuilderObj);
}
/**
* 全文搜索 之 多词搜索 高级客户端 同步
* @param index
* @param field
* @param param
* @return
*/
@GetMapping("/query/{index}/{field}/{param}")
public Object queryFullTextSearchInSub(
@PathVariable("index") String index,
@PathVariable("field") String field,
@PathVariable("param") String param
) throws IOException {
// 建立搜索对象SearchRequest
//指定索引名
SearchRequest searchRequestObj = new SearchRequest(index);// recruitment
//指定类型名
searchRequestObj.types("_doc");
//建立具体搜索对象SearchSourceBuilder,构建具体的搜索内容
SearchSourceBuilder searchSourceBuilderObj = new SearchSourceBuilder();
//通过SearchSourceBuilder对象的query方法指定搜索形式,通过QueryBuilders类的静态方法指定具体的搜索模式和目标字段及数值。
searchSourceBuilderObj.query(QueryBuilders.matchQuery(field,param ).operator(Operator.AND));//使用operator方法,表示多词的逻辑关系为AND field=technology,param=javaee c#
//searchSourceBuilderObj.query(QueryBuilders.matchQuery(field,param ));//没有使用operator方法,所以默认匹配到 "javaee"或者"c#"就都划入结果。
//分页查询:指定起始处
searchSourceBuilderObj.from(0);
//分页查询:指定返回的结果数量。
searchSourceBuilderObj.size(5);
// 设置超时时间,需要通过TimeValue对象来指定时间数值,该对象构造中的第一个参数为数值,第二个参数则是时间的单位,时间单位通过TimeUnit来指定。
searchSourceBuilderObj.timeout(new TimeValue(60, TimeUnit.SECONDS));
//通过搜索对象searchRequest的source方法,来将具体搜索对象SearchSourceBuilder中已经设定好的搜索参数交给搜索对象。
searchRequestObj.source(searchSourceBuilderObj);
//正式发起请求,并返回响应对象SearchResponse来查看响应回来的搜索结果和状态。
SearchResponse searchResponseObj = this.restHighLevelClientObj.search(searchRequestObj, RequestOptions.DEFAULT);//通过高级客户端对象restHighLevelClient的search方法来请求,需要将搜索对象交给search方法,冰
StringBuilder result = new StringBuilder();
//响应结果被封装到了泛型为SearchHit对象的集合(SearchHits对象)中,通过响应对象SearchResponse的getHits方法获取该集合(SearchHits对象)。
for (SearchHit hit : searchResponseObj.getHits()) {
result.append(hit.getSourceAsString()+"\n");//SearchHit对象的getSourceAsString方法用来获取Json格式的字符串结果。
}
return "搜索到"+searchResponseObj.getHits().totalHits+"条数据."+"\n"+result;//SearchHits对象的totalHits方法用来获取结果数目。
}
/**
* 指定id搜索 同步
* @param index
* @param id
* @return
* @throws IOException
*/
@GetMapping("/queryById/{index}/{id}")
public Object queryByIdSearch(@PathVariable("index") String index,@PathVariable("id") String id) throws IOException {
//创建get请求对象GetRequest,指定要请求的索引,类型,以及id
GetRequest getRequestObj = new GetRequest(index, "_doc", id);
//创建上下文获取对象FetchSourceContext,第一个参数为是否要返回文档内容,第二个参数中指定要返回的文档中的字段。
FetchSourceContext fetchSourceContextObj = new FetchSourceContext(true, new String[] {"_id","id","name","sex","tele","address","technology"}, Strings.EMPTY_ARRAY);
getRequestObj.fetchSourceContext(fetchSourceContextObj);//调用GetReponse对象的fetchSourceContext方法,指定一个上下文获取对象,从而配置上下文规则。
//调用高级客户端对象RestHighLevelClient的get方法,正式发起get请求,并返回通过get请求所得到的响应结果对象GetResponse
GetResponse getResponseObj = this.restHighLevelClientObj.get(getRequestObj, RequestOptions.DEFAULT);
return getResponseObj.getSource().toString();//通过GetResponse对象的getsource方法来获取响应过来的搜索结果。
}
/**
* 判断某个文档是否存在 同步
* @param index
* @param id
* @return
* @throws IOException
*/
@GetMapping("/exists/{index}/{id}")
public Object exists(@PathVariable("index") String index,@PathVariable("id") String id) throws IOException {
//创建get请求对象GetRequest,传入目标索引,类型,id
GetRequest getRequestObj = new GetRequest(index, "_doc", id);
//判断某个文档是否存在,只需要看响应结果就行了,因此这里的上下文获取对象创建时,传入false值,表示不返回文档内容。
FetchSourceContext fetchSourceContextObj = new FetchSourceContext(false);
getRequestObj.fetchSourceContext(fetchSourceContextObj);
//使用RestHighLevelClient高级客户端对象的exists方法发起判断请求.
boolean existsResult = this.restHighLevelClientObj.exists(getRequestObj, RequestOptions.DEFAULT);
return existsResult;
}
/**
* 添加文档 同步
* @return
* @throws IOException
*/
@GetMapping("/create")
public Object createTest() throws IOException {
//通过Map对象构建文档数据。
Map<String, Object> data = new HashMap<String, Object>();
data.put("id", 7);
data.put("name", "王梦柯");
data.put("sex", false);
data.put("tele", 8026073447l);
data.put("address", "长沙市天心区");
data.put("technology", "全栈 - JavaEE开发 beetl");
//创建文档添加对象IndexRequest,指定目标索引和类型
IndexRequest indexRequestObj = new IndexRequest("recruitment", "_doc");
indexRequestObj.source(data);//通过source方法来指定文档数据。
//通过restHighLevelClient高级客户端对象的index方法来正式发起添加文档的请求,并返回包含了响应信息的IndexReponse对象。
IndexResponse indexResponseObj = this.restHighLevelClientObj.index(indexRequestObj, RequestOptions.DEFAULT);
// IndexReponse对象的getResult方法用于返回添加是否成功,如:CRREATED,indexResponse的getShradInfo方法用于返回本次共计添加的文档数量,和成功添加的文档数量。
return indexResponseObj.getResult()+"\n"+indexResponseObj.getShardInfo();//CREATED ShardInfo{total=1, successful=1, failures=[]}
}
/**
* 更新文档 同步
* @return
* @throws IOException
*/
@GetMapping("/update")
public Object updateTest() throws IOException {
//创建文档更新对象UpdateRequest ,指定目标索引,类型,id
UpdateRequest updateRequestObj = new UpdateRequest("recruitment", "_doc", "AEKFNnkBAMnDLr4U5w0K");
//通过Map对象构建文档数据
Map<String, Object> data = new HashMap<String, Object>();
data.put("sex", true);
data.put("technology", "全栈 - JavaEE开发 beetl MongoDB ElasticSearch SpringBatch SpringBoot SpringCloud SSM Dubbo Zookeeper Redis Jsp Vue ElementUi Shrding-Jdbc");
updateRequestObj.doc(data);//通过UpdateRequest对象的doc方法指定数据
//通过RestHighLevelClient高级客户端对象的update方法来正式发起请求,并返回UpdateResponse对象,该对象可以获取响应结果。
UpdateResponse updateResponseObj = this.restHighLevelClientObj.update(updateRequestObj, RequestOptions.DEFAULT);
return updateResponseObj.getResult();//通过UpdateResponse对象的getResult方法来看是否更新成功,如果更新成功返回’UPDATED‘。
}
/**
* 删除文档
* @param index
* @param id
* @return
* @throws IOException
*/
@GetMapping("/delete/{index}/{id}")
public Object delete(@PathVariable("index") String index,@PathVariable("id") String id) throws IOException {
//创建文档删除对象DeleteRequest,指定目标索引,类型,id
DeleteRequest deleteRequestObj = new DeleteRequest(index, "_doc", id);
//通过RestHighLevelClient高级客户端对象的delete方法来正式发起删除请求,并返回DeleteResponse对象,该对象可以获取响应结果。
DeleteResponse deleteResponseObj = this.restHighLevelClientObj.delete(deleteRequestObj, RequestOptions.DEFAULT);
return deleteResponseObj.getResult();//DeleteResponse的getResult方法用于确认是否删除成果,如果删除成果返回'DELETED'。
}
}
异步操作增删改示例
/**
* 异步操作演示....
* @return
* @throws IOException
*/
@GetMapping("/async")
public Object asyncTest() throws Exception {
StringBuilder asyncResult = new StringBuilder();
// 发起请求一:异步全文搜索的多词搜索
SearchRequest searchRequestObj = new SearchRequest("recruitment");
searchRequestObj.types("_doc");
SearchSourceBuilder searchSourceBuilderObj = new SearchSourceBuilder();
searchSourceBuilderObj.query(QueryBuilders.matchQuery("technology", "vue elementui").operator(Operator.AND));
searchSourceBuilderObj.timeout(new TimeValue(30, TimeUnit.SECONDS));
searchRequestObj.source(searchSourceBuilderObj);
this.restHighLevelClientObj.searchAsync(searchRequestObj, RequestOptions.DEFAULT, new ActionListener<SearchResponse>() {
//操作成功时调用
@Override
public void onResponse(SearchResponse response) {
// TODO Auto-generated method stub
asyncResult.append("高级搜索成功...\n");
for (SearchHit his : response.getHits()) {
asyncResult.append(his.getSourceAsString()+"\n");
}
}
//操作失败时调用
@Override
public void onFailure(Exception e) {
asyncResult.append("高级搜索失败...\n");
System.out.println("操作失败。。。。异常信息为:"+e.getMessage()+" 异常类型为"+e.getClass().toString());
}
});
// 发起请求二:指定Id,异步搜索文档。
GetRequest getRequestObj = new GetRequest("recruitment", "_doc", "RPuuF3kBhcx63ZgbAOA8");
getRequestObj.fetchSourceContext(new FetchSourceContext(true, new String[] {"_id","id","name","sex","tele","address","technology"}, Strings.EMPTY_ARRAY));
this.restHighLevelClientObj.getAsync(getRequestObj, RequestOptions.DEFAULT, new ActionListener<GetResponse>() {
@Override
public void onResponse(GetResponse response) {
// TODO Auto-generated method stub
asyncResult.append("指定id搜索成功....\n");
asyncResult.append(response.getSource().toString()+" \n");
}
@Override
public void onFailure(Exception e) {
asyncResult.append("指定id搜索失败....\n");
}
});
// 发起请求三:异步判断文档是否存在
//return asynResult;
getRequestObj.fetchSourceContext(new FetchSourceContext(false));
this.restHighLevelClientObj.existsAsync(getRequestObj, RequestOptions.DEFAULT, new ActionListener<Boolean>() {
@Override
public void onResponse(Boolean response) {
asyncResult.append("异步判断操作成功... \n");
asyncResult.append(response+" \n");
}
@Override
public void onFailure(Exception e) {
asyncResult.append("异步判断操作失败。。。\n");
}
});
// 发起请求四:添加文档
Map<String, Object> data = new HashMap<String, Object>();
data.put("id", 7);
data.put("name", "王梦柯");
data.put("sex", false);
data.put("tele", 8026073447l);
data.put("address", "长沙市天心区");
data.put("technology", "全栈 - JavaEE开发 beetl");
IndexRequest indexRequestObj = new IndexRequest("recruitment", "_doc");
indexRequestObj.source(data);
this.restHighLevelClientObj.indexAsync(indexRequestObj, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() {
@Override
public void onResponse(IndexResponse indexResponse) {
asyncResult.append("异步添加操作成功。。。。\n");
asyncResult.append(indexResponse.getResult()+" "+indexResponse.getShardInfo()+" \n");
}
@Override
public void onFailure(Exception e) {
asyncResult.append("异步添加操作失败。。。。\n");
}
});
Thread.sleep(5000);//延迟五秒,不然数据还没查出来,asyncResult变量的值便会是空的。
System.out.println(asyncResult);
return asyncResult;
}
代码下载
链接: https://pan.baidu.com/s/1Vs2o5UzbgMDCNpqR2WPzJA
提取码: 9rdm