JAVA-API调用ES
Gitee源码:https://gitee.com/yhhua940103/es_demo.git
将用户表数据加到ES
id | name | age | sex?男 | address |
---|---|---|---|---|
1 | 张三 | 10 | true | 江苏苏州 |
2 | 李四 | 20 | true | 苏州园区 |
3 | 王芳 | 30 | false | 园区华为 |
4 | 赵六 | 40 | false | 华为汽车 |
引入依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>es_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- ES的高阶的客户端API -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.1</version>
</dependency>
<!-- 阿里巴巴出品的一款将Java对象转换为JSON、将JSON转换为Java对象的库 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<target>1.8</target>
<source>1.8</source>
</configuration>
</plugin>
</plugins>
</build>
</project>
用户实体
package elasticsearch.entity;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
/**
* @description: 用户信息
* @author YHH
* @date 2022-05-0313:50
*/
public class UserInfo
{
@JSONField(serialize = false)
private long id;
private String name;
private Integer age;
//是男?
private Boolean sex;
private String address;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getSex() {
return sex;
}
public void setSex(Boolean sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return id + ":" + JSONObject.toJSONString(this);
}
}
用户接口
package elasticsearch.service;
import elasticsearch.entity.UserInfo;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* @description: 用户crud
* @author YHH
* @date 2022-05-0313:53
*/
public interface UserInfoFullTextService
{
/**
* 添加用户
* @param userInfo
*/
void add(UserInfo userInfo) throws IOException;
/**
* 查找用户
* @param id
* @return
*/
UserInfo findUserById(long id) throws IOException;
/**
* 更新用户
*/
void update(UserInfo userInfo) throws IOException;
/**
* 删除用户
*/
void deleteUserById(long id) throws IOException;
/**
* 根据关键字检索
*/
List<UserInfo> searchUserByKeyWords(String keywords) throws IOException;
/**
* 分页检索
*/
Map<String, Object> searchUserByPage(String keywords, int pageNum, int pageSize) throws IOException;
/**
* scroll分页搜索【会一次查出来,后续根据scroll id从缓存中查找】
*/
Map<String, Object> searchByScrollPage(String keyWords, String scrollId, int pageSize) throws IOException;
/**
* 关闭ES连接
*/
void close() throws IOException;
}
用户实现类
package elasticsearch.service.impl;
import com.alibaba.fastjson.JSONObject;
import elasticsearch.entity.JobDetail;
import elasticsearch.entity.UserInfo;
import elasticsearch.service.UserInfoFullTextService;
import org.apache.http.HttpHost;
import org.elasticsearch.action.delete.DeleteRequest;
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.search.SearchScrollRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @description: 用户crud实现类
* @author YHH
* @date 2022-05-0314:00
*/
public class UserInfoFullTextServiceImpl implements UserInfoFullTextService
{
private RestHighLevelClient restHighLevelClient;
// 用户索引库
private static final String USER_IDX = "user_index";
public UserInfoFullTextServiceImpl() {
//单节点
RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost("192.168.0.121", 9200, "http"));
restHighLevelClient = new RestHighLevelClient(restClientBuilder);
//集群
// RestClientBuilder restClientBuilder = RestClient.builder(
// new HttpHost("ip", 9200, "http")
// , new HttpHost("ip", 9200, "http")
// , new HttpHost("ip", 9200, "http"));
}
/**
* 添加用户
* @param userInfo
*/
@Override
public void add(UserInfo userInfo) throws IOException {
//1. 构建IndexRequest对象,用来描述ES发起请求的数据。
IndexRequest indexRequest = new IndexRequest(USER_IDX);
//2. 设置文档ID。
indexRequest.id(userInfo.getId() + "");
//3. 使用FastJSON将实体类对象转换为JSON。
String json = JSONObject.toJSONString(userInfo);
//4. 使用IndexRequest.source方法设置文档数据,并设置请求的数据为JSON格式。
indexRequest.source(json, XContentType.JSON);
//5. 使用ES High level client调用index方法发起请求,将一个文档添加到索引中。
IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(index);
}
/**
* 查找用户
* @param id
* @return
*/
@Override
public UserInfo findUserById(long id) throws IOException {
// 1. 构建GetRequest请求。
GetRequest getRequest = new GetRequest(USER_IDX, id + "");
// 2. 使用RestHighLevelClient.get发送GetRequest请求,并获取到ES服务器的响应。
GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
// 3. 将ES响应的数据转换为JSON字符串
String json = getResponse.getSourceAsString();
// 4. 并使用FastJSON将JSON字符串转换为JobDetail类对象
UserInfo userInfo = JSONObject.parseObject(json, UserInfo.class);
// 5. 记得:单独设置ID
userInfo.setId(id);
return userInfo;
}
/**
* 更新用户
* @param userInfo
*/
@Override
public void update(UserInfo userInfo) throws IOException {
// 1. 判断对应ID的文档是否存在
// a) 构建GetRequest
GetRequest getRequest = new GetRequest(USER_IDX, userInfo.getId() + "");
// b) 执行client的exists方法,发起请求,判断是否存在
boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
if (exists) {
// 2. 构建UpdateRequest请求
UpdateRequest updateRequest = new UpdateRequest(USER_IDX, userInfo.getId() + "");
// 3. 设置UpdateRequest的文档,并配置为JSON格式
updateRequest.doc(JSONObject.toJSONString(userInfo), XContentType.JSON);
// 4. 执行client发起update请求
restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
}
}
/**
* 删除用户
* @param id
*/
@Override
public void deleteUserById(long id) throws IOException {
// 1. 构建delete请求
DeleteRequest deleteRequest = new DeleteRequest(USER_IDX, id + "");
// 2. 使用RestHighLevelClient执行delete请求
restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
}
/**
* 根据关键字检索
* @param keywords
*/
@Override
public List<UserInfo> searchUserByKeyWords(String keywords) throws IOException {
// 1.构建SearchRequest检索请求
// 专门用来进行全文检索、关键字检索的API
SearchRequest searchRequest = new SearchRequest(USER_IDX);
// 2.创建一个SearchSourceBuilder专门用于构建查询条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 3.使用QueryBuilders.multiMatchQuery构建一个查询条件(搜索title、jd),并配置到SearchSourceBuilder
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keywords, "name", "address");
// 将查询条件设置到查询请求构建器中
searchSourceBuilder.query(multiMatchQueryBuilder);
// 4.调用SearchRequest.source将查询条件设置到检索请求
searchRequest.source(searchSourceBuilder);
// 5.执行RestHighLevelClient.search发起请求
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hitArray = searchResponse.getHits().getHits();
// 6.遍历结果
ArrayList<UserInfo> userInfoArrayList = new ArrayList<>();
for (SearchHit documentFields : hitArray) {
// 1)获取命中的结果
String json = documentFields.getSourceAsString();
// 2)将JSON字符串转换为对象
UserInfo userInfo = JSONObject.parseObject(json, UserInfo.class);
// 3)使用SearchHit.getId设置文档ID
userInfo.setId(Long.parseLong(documentFields.getId()));
userInfoArrayList.add(userInfo);
}
return userInfoArrayList;
}
/**
* 分页检索
* @param keywords
* @param pageNum
* @param pageSize
*/
@Override
public Map<String, Object> searchUserByPage(String keywords, int pageNum, int pageSize) throws IOException {
// 1.构建SearchRequest检索请求
// 专门用来进行全文检索、关键字检索的API
SearchRequest searchRequest = new SearchRequest(USER_IDX);
// 2.创建一个SearchSourceBuilder专门用于构建查询条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 3.使用QueryBuilders.multiMatchQuery构建一个查询条件(搜索title、jd),并配置到SearchSourceBuilder
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keywords, "name", "address");
// 将查询条件设置到查询请求构建器中
searchSourceBuilder.query(multiMatchQueryBuilder);
// 每页显示多少条
searchSourceBuilder.size(pageSize);
// 设置从第几条开始查询
searchSourceBuilder.from((pageNum - 1) * pageSize);
// 4.调用SearchRequest.source将查询条件设置到检索请求
searchRequest.source(searchSourceBuilder);
// 5.执行RestHighLevelClient.search发起请求
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hitArray = searchResponse.getHits().getHits();
// 6.遍历结果
ArrayList<UserInfo> userInfoArrayList = new ArrayList<>();
for (SearchHit documentFields : hitArray) {
// 1)获取命中的结果
String json = documentFields.getSourceAsString();
// 2)将JSON字符串转换为对象
UserInfo userInfo = JSONObject.parseObject(json, UserInfo.class);
// 3)使用SearchHit.getId设置文档ID
userInfo.setId(Long.parseLong(documentFields.getId()));
userInfoArrayList.add(userInfo);
}
// 8. 将结果封装到Map结构中(带有分页信息)
// a) total -> 使用SearchHits.getTotalHits().value获取到所有的记录数
// b) content -> 当前分页中的数据
long totalNum = searchResponse.getHits().getTotalHits().value;
HashMap hashMap = new HashMap();
hashMap.put("total", totalNum);
hashMap.put("content", userInfoArrayList);
return hashMap;
}
/**
* scroll分页搜索【会一次查出来,后续根据scroll id从缓存中查找】
* @param keyWords
* @param scrollId
* @param pageSize
*/
@Override
public Map<String, Object> searchByScrollPage(String keyWords, String scrollId, int pageSize) throws IOException {
SearchResponse searchResponse = null;
if (scrollId == null) {
// 1.构建SearchRequest检索请求
// 专门用来进行全文检索、关键字检索的API
SearchRequest searchRequest = new SearchRequest(USER_IDX);
// 2.创建一个SearchSourceBuilder专门用于构建查询条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 3.使用QueryBuilders.multiMatchQuery构建一个查询条件(搜索title、jd),并配置到SearchSourceBuilder
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyWords, "name", "address");
// 将查询条件设置到查询请求构建器中
searchSourceBuilder.query(multiMatchQueryBuilder);
// 设置高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("name");
highlightBuilder.field("address");
highlightBuilder.preTags("<font color='red'>");
highlightBuilder.postTags("</font>");
// 给请求设置高亮
searchSourceBuilder.highlighter(highlightBuilder);
// 每页显示多少条
searchSourceBuilder.size(pageSize);
// 4.调用SearchRequest.source将查询条件设置到检索请求
searchRequest.source(searchSourceBuilder);
//--------------------------
// 设置scroll查询
//--------------------------
searchRequest.scroll(TimeValue.timeValueMinutes(5));
// 5.执行RestHighLevelClient.search发起请求
searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
}
// 第二次查询的时候,直接通过scroll id查询数据
else {
SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
searchScrollRequest.scroll(TimeValue.timeValueMinutes(5));
// 使用RestHighLevelClient发送scroll请求
searchResponse = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT);
}
//--------------------------
// 迭代ES响应的数据
//--------------------------
SearchHit[] hitArray = searchResponse.getHits().getHits();
// 6.遍历结果
ArrayList<UserInfo> userInfoArrayList = new ArrayList<>();
for (SearchHit documentFields : hitArray) {
// 1)获取命中的结果
String json = documentFields.getSourceAsString();
// 2)将JSON字符串转换为对象
UserInfo userInfo = JSONObject.parseObject(json, UserInfo.class);
// 3)使用SearchHit.getId设置文档ID
userInfo.setId(Long.parseLong(documentFields.getId()));
userInfoArrayList.add(userInfo);
// 设置高亮的一些文本到实体类中
// 封装了高亮
Map<String, HighlightField> highlightFieldMap = documentFields.getHighlightFields();
HighlightField titleHL = highlightFieldMap.get("name");
HighlightField jdHL = highlightFieldMap.get("address");
if (titleHL != null) {
// 获取指定字段的高亮片段
Text[] fragments = titleHL.getFragments();
// 将这些高亮片段拼接成一个完整的高亮字段
StringBuilder builder = new StringBuilder();
for (Text text : fragments) {
builder.append(text);
}
// 设置到实体类中
userInfo.setName(builder.toString());
}
if (jdHL != null) {
// 获取指定字段的高亮片段
Text[] fragments = jdHL.getFragments();
// 将这些高亮片段拼接成一个完整的高亮字段
StringBuilder builder = new StringBuilder();
for (Text text : fragments) {
builder.append(text);
}
// 设置到实体类中
userInfo.setAddress(builder.toString());
}
}
// 8. 将结果封装到Map结构中(带有分页信息)
// a) total -> 使用SearchHits.getTotalHits().value获取到所有的记录数
// b) content -> 当前分页中的数据
long totalNum = searchResponse.getHits().getTotalHits().value;
HashMap hashMap = new HashMap();
hashMap.put("scroll_id", searchResponse.getScrollId());
hashMap.put("content", userInfoArrayList);
return hashMap;
}
/**
* 关闭ES连接
*/
@Override
public void close() throws IOException {
restHighLevelClient.close();
}
}
测试类
package service;
import elasticsearch.entity.UserInfo;
import elasticsearch.service.UserInfoFullTextService;
import elasticsearch.service.impl.UserInfoFullTextServiceImpl;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/*
* 用户测试类
* */
public class UserInfoFullTextServiceTest
{
private UserInfoFullTextService userInfoFullTextService;
@BeforeTest
public void beforeTest() {
userInfoFullTextService = new UserInfoFullTextServiceImpl();
}
@Test
public void addTest() throws IOException {
UserInfo userInfo = new UserInfo();
userInfo.setId(1);
userInfo.setName("张三");
userInfo.setAge(10);
userInfo.setSex(true);
userInfo.setAddress("江苏苏州");
userInfoFullTextService.add(userInfo);
UserInfo userInfo2 = new UserInfo();
userInfo2.setId(2);
userInfo2.setName("李四");
userInfo2.setAge(20);
userInfo2.setSex(true);
userInfo2.setAddress("苏州园区");
userInfoFullTextService.add(userInfo2);
UserInfo userInfo3 = new UserInfo();
userInfo3.setId(3);
userInfo3.setName("王芳");
userInfo3.setAge(30);
userInfo3.setSex(false);
userInfo3.setAddress("园区华为");
userInfoFullTextService.add(userInfo3);
UserInfo userInfo4 = new UserInfo();
userInfo4.setId(4);
userInfo4.setName("赵六");
userInfo4.setAge(40);
userInfo4.setSex(false);
userInfo4.setAddress("华为汽车");
userInfoFullTextService.add(userInfo4);
}
@Test
public void getTest() throws IOException {
System.out.println(userInfoFullTextService.findUserById(1));
}
@Test
public void updateTest() throws IOException {
UserInfo userInfo = userInfoFullTextService.findUserById(1);
userInfo.setAddress("广州佛山");
userInfoFullTextService.update(userInfo);
}
@Test
public void deleteTest() throws IOException {
userInfoFullTextService.deleteUserById(1);
searchByPageTest();
}
@Test
public void searchTest() throws IOException {
List<UserInfo> userInfoList = userInfoFullTextService.searchUserByKeyWords("苏州");
for (UserInfo userInfo : userInfoList) {
System.out.println(userInfo);
}
}
@Test
public void searchByPageTest() throws IOException {
Map<String, Object> resultMap = userInfoFullTextService.searchUserByPage("苏州", 1, 3);
System.out.println("一共查询到:" + resultMap.get("total").toString());
ArrayList<UserInfo> content = (ArrayList<UserInfo>) resultMap.get("content");
for (UserInfo userInfo : content) {
System.out.println(userInfo);
}
}
@Test
public void searchByScrollPageTest1() throws IOException {
Map<String, Object> resultMap = userInfoFullTextService.searchByScrollPage("苏州", null, 1);
String scroll_id = resultMap.get("scroll_id").toString();
System.out.println("scroll_id:" + scroll_id);
ArrayList<UserInfo> content = (ArrayList<UserInfo>) resultMap.get("content");
for (UserInfo userInfo : content) {
System.out.println(userInfo);
}
System.out.println("------------------------------------");
searchByScrollPageTest2(scroll_id);
}
@Test
public void searchByScrollPageTest2(String scroll_id) throws IOException {
Map<String, Object> resultMap = userInfoFullTextService.searchByScrollPage("spark", scroll_id, 1);
System.out.println("scroll_id:" + resultMap.get("scroll_id").toString());
ArrayList<UserInfo> content = (ArrayList<UserInfo>) resultMap.get("content");
for (UserInfo userInfo : content) {
System.out.println(userInfo);
}
}
@AfterTest
public void afterTest() throws IOException {
userInfoFullTextService.close();
}
}