ES提供多种不同的客户端:
1、TransportClient
ES提供的传统客户端,官方计划8.0版本删除此客户端。
2、RestClient
RestClient是官方推荐使用的,它包括两种:Java Low Level REST Client和 Java High Level REST Client。
ES在6.0之后提供 Java High Level REST Client, 两种客户端官方更推荐使用 Java High Level REST Client,不过当 前它还处于完善中,有些功能还没有。
本教程准备采用 Java High Level REST Client,如果它有不支持的功能,则使用Java Low Level REST Client。
一:添加依赖:
<!--es搜索引擎-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.4.3</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.4.3</version>
</dependency>
二:配置文件application.peopertity
elasticsearch.hostlist:${eshostlist:127.0.0.1:9200}//名字这一行随便写,但是IP和端口号必须写 正确的
spring.data.elasticsearch.repositories.enabled = true
spring.data.elasticsearch.cluster-nodes =127.0.0.1:9300
spring.main.allow-bean-definition-overriding=true
三:配置类
创建 config 包,把配置类放 config包中
package com.qishimai.mybatisplus.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author 王文龙
* @Date 2019-07-30 16:46
*/
@Configuration
public class ElasticsearchConfig {
@Value("${elasticsearch.hostlist}”)//这里跟 application.peopertity 的配置一一对应,按住ctrl+鼠标左键,能跳转到到application中,说明没问题
private String hostlist;
@Bean
public RestHighLevelClient restHighLevelClient(){
//解析hostlist配置信息
String[] split = hostlist.split(",");
//创建HttpHost数组,其中存放es主机和端口号的配置信息
HttpHost[] httpHostArray = new HttpHost[split.length];
for (int i = 0; i < split.length; i++) {
String item = split[i];
httpHostArray[i]= new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http");
}
//创建RestHighLevelClient客户端
return new RestHighLevelClient(RestClient.builder(httpHostArray));
}
//项目主要使用RestHighLevelClient,对于低级的客户端暂时不用
@Bean
public RestClient restClient(){
//解析hostList配置信息
String[] split = hostlist.split(",");
//创建HttpHost数组,其中存放es主机和端口的配置信息
HttpHost[] httpHosts = new HttpHost[split.length];
for (int i = 0; i <split.length ; i++) {
String item = split[i];
httpHosts[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http");
}
return RestClient.builder(httpHosts).build();
}
}
三:启动类
@SpringBootApplication
@EntityScan("com.qishimai.mybatisplus.pojo")
@MapperScan("com.qishimai.mybatisplus.Mapper")
@ComponentScan("com.qishimai.mybatisplus.service")
@ComponentScan("com.qishimai.mybatisplus.controller")
public class MybatisplusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisplusApplication.class, args);
}
}
启动ES程序和head插件
四:测试类测试(增删改查)
package com.qishimai.mybatisplus.test;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
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.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @Author 王文龙
* @Date 2019-07-30 17:55
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex {
@Autowired
RestHighLevelClient client;
@Autowired
RestClient restClient;
//创建索引库
@Test
public void testCtrateIndex() throws IOException {
//创建索引请求对象,并设置索引名称
CreateIndexRequest xc_course = new CreateIndexRequest("xc_course");
//设置索引参数
xc_course.settings(Settings.builder().put("number_of_shards", 1).put("number_of_replicas", 0));
//设置映射
xc_course.mapping("doc", " {\n" +
" \"properties\": {\n" +
" \"name\": {\"type\": \"text\"," +
" \"analyzer\":\"ik_max_word\"," +
" \"search_analyzer\":\"ik_smart\"}," +
" \"description\": { \"type\": \"text\"," +
" \"analyzer\":\"ik_max_word\"," +
" \"search_analyzer\":\"ik_smart\"" +
" }, \"studymodel\": {" +
" \"type\": \"keyword\" }," +
" \"price\": {\"type\": \"float\"" +
" }}}", XContentType.JSON);
//创建索引操作客户端
IndicesClient indices = client.indices();
//创建响应对象
CreateIndexResponse createIndexResponse = indices.create(xc_course);
//得到响应结果
boolean acknowledged = createIndexResponse.isAcknowledged();
System.err.println(acknowledged);
}
//删除索引库
@Test
public void testDeleteIndex() throws IOException {
//删除索引请求对象
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("xc_course");
//删除索引
DeleteIndexResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest);
//删除索引响应结果
boolean acknowledged = deleteIndexResponse.isAcknowledged();
System.err.println(acknowledged);
}
//添加文档
@Test
public void testAddDoc() throws IOException {
//准备json数据
HashMap<String, Object> jsonMap = new HashMap<>();
jsonMap.put("name", "spring cloud实战");
jsonMap.put("description", "本课程主要从四个章节进行讲解: 1.微服务架构入门 2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。");
jsonMap.put("studymodel", "201001");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy‐MM‐dd HH:mm:ss");
jsonMap.put("timestamp", dateFormat.format(new Date()));
jsonMap.put("price", 5.6f);
//索引请求对象
IndexRequest indexRequest = new IndexRequest("xc_course", "doc","1");
//指定索引文档内容
indexRequest.source(jsonMap);
//索引响应对象
IndexResponse indexResponse = client.index(indexRequest);
//获取响应结果
DocWriteResponse.Result result = indexResponse.getResult();
System.out.println(result);
}
//查询文档
@Test
public void getDoc() throws IOException {
GetRequest getRequest = new GetRequest("xc_course", "doc", "1");
GetResponse getResponse = client.get(getRequest);
boolean exists = getResponse.isExists();
Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
System.out.println(sourceAsMap);
}
//更新文档
@Test
public void updateDoc() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("xc_course", "doc", "1");
HashMap<String, Object> map = new HashMap<>();
map.put("name","尚佳鹏 退真粗");
updateRequest.doc(map);
UpdateResponse update = client.update(updateRequest);
RestStatus status = update.status();
System.out.println(status);
}
//根据id删除文档
@Test
public void testDelDoc() throws IOException {
//删除文档id
String id = "za20RmwByvlw6JcpzSrz";
//删除索引请求对象
DeleteRequest deleteRequest = new DeleteRequest("xc_course", "doc", id);
//响应对象
DeleteResponse delete = client.delete(deleteRequest);
//获取响应结果
DocWriteResponse.Result result = delete.getResult();
System.out.println(result);
}
}
四.1测试类测试(查询)
package com.qishimai.mybatisplus.test;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @Author 王文龙
* @Date 2019-07-31 15:22
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestSearch {
@Autowired
RestHighLevelClient client;
@Autowired
RestClient restClient;
//搜索type下的全部记录
@Test
public void testSearchAll() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_wang");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{"name", "studymodel"}, new String[]{});
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
String index = hit.getIndex();
String type = hit.getType();
String id = hit.getId();
float score = hit.getScore();
String sourceAsString = hit.getSourceAsString();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String studymodel = (String) sourceAsMap.get("studymodel");
String description = (String) sourceAsMap.get("description");
System.out.println(name);
System.out.println(studymodel);
System.out.println(description);
}
}
//搜索type下的全部记录+分页
@Test
public void testSearchAllPage() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_wang");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//分页查询 , 设置起始下标,从0开始
searchSourceBuilder.from(0);
//每页显示条数
searchSourceBuilder.size(2);
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{"name", "studymodel"}, new String[]{});
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
String index = hit.getIndex();
String type = hit.getType();
String id = hit.getId();
float score = hit.getScore();
String sourceAsString = hit.getSourceAsString();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String studymodel = (String) sourceAsMap.get("studymodel");
String description = (String) sourceAsMap.get("description");
System.out.println(name);
System.out.println(studymodel);
System.out.println(description);
}
}
//Term Query 精确查询
@Test
public void findByName() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_wang");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("name", "spring"));
//source源字段过滤
searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "description"}, new String[]{});
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
String index = hit.getIndex();
String type = hit.getType();
String id = hit.getId();
float score = hit.getScore();
String sourceAsString = hit.getSourceAsString();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String studymodel = (String) sourceAsMap.get("studymodel");
String description = (String) sourceAsMap.get("description");
System.out.println(name);
System.out.println(studymodel);
System.out.println(description);
}
}
//根据id精确匹配
@Test
public void findById() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_wang");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
String[] strings = new String[]{"1", "2"};
List<String> idList = Arrays.asList(strings);
searchSourceBuilder.query(QueryBuilders.termsQuery("_id", idList));
//source源字段过滤
searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "description"}, new String[]{});
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
System.err.println(hit);
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
System.out.println(sourceAsMap);
String name = (String) sourceAsMap.get("name");
String studymodel = (String) sourceAsMap.get("studymodel");
String description = (String) sourceAsMap.get("description");
System.out.println(name);
System.out.println(studymodel);
System.out.println(description);
}
}
//根据关键字搜索
@Test
public void testMatchQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_wang");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//source源字段过滤
searchSourceBuilder.fetchSource(new String[]{"name", "studymodel"}, new String[]{});
//匹配关键字
searchSourceBuilder.query(QueryBuilders.matchQuery("description", "spring基础").operator(Operator.OR));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
System.out.println(hit);
System.err.println(hit.getSourceAsString());
System.out.println(hit.getSourceAsMap().get("name"));
System.out.println(hit.getSourceAsMap().get("studymodel"));
}
}
//分词器搜索 matchQuery 一次只能匹配一个Field,
@Test
public void testMatchQueryIk() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_wang");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//source源字段过滤
searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "description"}, new String[]{});
//匹配关键字
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("description", "前台页面开发框架 架 构").minimumShouldMatch("80%");//设置匹配占比
searchSourceBuilder.query(matchQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
System.out.println(hit);
System.err.println(hit.getSourceAsString());
System.out.println(hit.getSourceAsMap().get("name"));
System.out.println(hit.getSourceAsMap().get("studymodel"));
System.out.println(hit.getSourceAsMap().get("description"));
}
}
//分词器搜索 提升权重,谁的权重高 出现谁的关键字时 排在最前面
@Test
public void testMatchQueryQZ() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_wang");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//source源字段过滤
searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "description"}, new String[]{});
//匹配关键字
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring轻松", "name", "description")
.minimumShouldMatch("50%");//设置匹配占比
multiMatchQueryBuilder.field("name", 10);//提升boost
searchSourceBuilder.query(multiMatchQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
System.out.println(hit);
System.err.println(hit.getSourceAsString());
System.out.println(hit.getSourceAsMap().get("name"));
System.out.println(hit.getSourceAsMap().get("studymodel"));
System.out.println(hit.getSourceAsMap().get("description"));
}
}
//BoolQuery 将搜索关键字分词,拿分词去索引库搜索
@Test
public void testBoolQuery() throws IOException {
//创建搜索请求对象
SearchRequest searchRequest = new SearchRequest("xc_wang");
searchRequest.types("doc");
//创建索引源配置对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.fetchSource(new String[]{"name", "pic", "studymodel"}, new String[]{});
//multiQuery
String keyword = "spring开发框架";
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring框架", "name", "description").minimumShouldMatch("50%");
//TermQuery
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("studymodel", "201001");
//布尔查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
boolQueryBuilder.must(termQueryBuilder);
//设置布尔查询对象
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);//设置搜索源配置
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
System.out.println(hit);
System.err.println(hit.getSourceAsMap());
}
}
//布尔查询使用过滤器
@Test
public void testFilter() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_wang");
searchRequest.types("doc");
//利用builder过滤字段
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//过滤字段
searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "description"}, new String[]{});
searchRequest.source(SearchSourceBuilder.searchSource());
//匹配字段
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring框架", "name", "description");
//设置匹配占比
multiMatchQueryBuilder.minimumShouldMatch("50%");
//提升另个字段的Bost值
multiMatchQueryBuilder.field("name", 10);
searchSourceBuilder.query(multiMatchQueryBuilder);
//布尔查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(searchSourceBuilder.query());
//过滤
boolQueryBuilder.filter(QueryBuilders.termQuery("studymodel", "201001"));
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(60).lte(100));
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
System.out.println(hit);
System.err.println(hit.getSourceAsMap());
}
}
// 排序
@Test
public void testSort() throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_wang").types("doc");
//过滤字段
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().fetchSource(new String[]{"name", "studymodel", "price", "description"}, new String[]{});
searchRequest.source(searchSourceBuilder);
//布尔查询
QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery("price").gte(0).lte(100));
//排序
searchSourceBuilder.sort(new FieldSortBuilder("studymodel").order(SortOrder.DESC));
searchSourceBuilder.sort(new FieldSortBuilder("price").order(SortOrder.ASC));
SearchHit[] hits = client.search(searchRequest).getHits().getHits();
for (SearchHit hit : hits) {
System.out.println(hit);
System.err.println(hit.getSourceAsMap().get("name"));
System.err.println(hit.getSourceAsMap().get("studymodel"));
System.err.println(hit.getSourceAsMap().get("price"));
System.err.println(hit.getSourceAsMap().get("description"));
}
}
//高亮显示
@Test
public void testHighlight () throws IOException {
SearchRequest searchRequest = new SearchRequest("xc_wang");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "description"}, new String[]{});
searchRequest.source(searchSourceBuilder); //匹配关键字
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("开发", "name", "description");
searchSourceBuilder.query(multiMatchQueryBuilder); //布尔查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(searchSourceBuilder.query());
//过虑
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100));
//排序
searchSourceBuilder.sort(new FieldSortBuilder("studymodel").order(SortOrder.DESC));
searchSourceBuilder.sort(new FieldSortBuilder("price").order(SortOrder.ASC));
//高亮设置
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<tag>");
//设置前缀
highlightBuilder.postTags("</tag>");
//设置后缀
// 设置高亮字段
highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
highlightBuilder.fields().add(new HighlightBuilder.Field("description"));
searchSourceBuilder.highlighter(highlightBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//名称
String name = (String) sourceAsMap.get("name");
//取出高亮字段内容
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (highlightFields != null) {
HighlightField nameField = highlightFields.get("name");
if (nameField != null) {
Text[] fragments = nameField.getFragments();
StringBuffer stringBuffer = new StringBuffer();
for (Text str : fragments) {
stringBuffer.append(str.string());
}
name = stringBuffer.toString();
}
}
String studymodel = (String) sourceAsMap.get("studymodel");
String description = (String) sourceAsMap.get("description");
System.out.println(name);
System.out.println(studymodel);
System.out.println(description);
}
}
}