跟乐乐学ES!(四) java中ElasticSearch客户端的使用。

上一篇文章:跟乐乐学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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值