Elasticsearch常用Java API编程
Posted 赵广陆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch常用Java API编程相关的知识,希望对你有一定的参考价值。
目录
1 环境准备
预备知识:
1.ElasticSearch快速入门
2.SpringData ElasticSearch
3.ElasticSearch高级操作
要将搜索的功能与前端对接,我们必须要使用Java代码来实现对Elasticsearch的操作。由于之前这些文章中的?JavaApi都是散装的所以用这一篇进行汇总.
官网API地址:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high.html
1.1 准备IDEA项目结构
-
创建elasticsearch_example项目
-
创建包结构如下所示
1.2 准备POM依赖
<repositories><!-- 代码库 -->
<repository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
<dependencies>
<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>
<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>
1.3 创建用于保存职位信息的实体类
注意:
在id字段上添加一个 @JSONField注解,并配置注解的serialize为false,表示该字段无需转换为JSON,因为它就是文档的唯一ID。
参考代码:
public class JobDetail
// 因为此处无需将id序列化为文档中
@JSONField(serialize = false)
private long id; // 唯一标识
private String area; // 职位所在区域
private String exp; // 岗位要求的工作经验
private String edu; // 学历要求
private String salary; // 薪资范围
private String job_type; // 职位类型(全职/兼职)
private String cmp; // 公司名
private String pv; // 浏览量
private String title; // 岗位名称
private String jd; // 职位描述
public long getId()
return id;
public void setId(long id)
this.id = id;
public String getArea()
return area;
public void setArea(String area)
this.area = area;
public String getExp()
return exp;
public void setExp(String exp)
this.exp = exp;
public String getEdu()
return edu;
public void setEdu(String edu)
this.edu = edu;
public String getSalary()
return salary;
public void setSalary(String salary)
this.salary = salary;
public String getJob_type()
return job_type;
public void setJob_type(String job_type)
this.job_type = job_type;
public String getCmp()
return cmp;
public void setCmp(String cmp)
this.cmp = cmp;
public String getPv()
return pv;
public void setPv(String pv)
this.pv = pv;
public String getTitle()
return title;
public void setTitle(String title)
this.title = title;
public String getJd()
return jd;
public void setJd(String jd)
this.jd = jd;
@Override
public String toString()
return "JobDetail" +
"id=" + id +
", area='" + area + '\\'' +
", exp='" + exp + '\\'' +
", edu='" + edu + '\\'' +
", salary='" + salary + '\\'' +
", job_type='" + job_type + '\\'' +
", cmp='" + cmp + '\\'' +
", pv='" + pv + '\\'' +
", title='" + title + '\\'' +
", jd='" + jd + '\\'' +
'';
1.4 编写接口和实现类
在cn.itcast.elasticsearch.service包中创建JobFullTextService接口,该接口中定义了职位全文检索相关的Java API接口。满足基本的增删改查
参考代码:
/**
* 定义JobFullTextService
*/
public interface JobFullTextService
// 添加一个职位数据
void add(JobDetail jobDetail);
// 根据ID检索指定职位数据
JobDetail findById(long id) throws IOException;
// 修改职位薪资
void update(JobDetail jobDetail) throws IOException;
// 根据ID删除指定位置数据
void deleteById(long id) throws IOException;
// 根据关键字检索数据
List<JobDetail> searchByKeywords(String keywords) throws IOException;
// 分页检索
Map<String, Object> searchByPage(String keywords, int pageNum, int pageSize) throws IOException;
// scroll分页解决深分页问题
Map<String, Object> searchByScrollPage(String keywords, String scrollId, int pageSize) throws IOException;
// 关闭ES连接
void close() throws IOException;
;
1.5 创建实现类
在cn.itcast.elasticsearch.service.impl包下创建一个实现类:JobFullTextServiceImpl,并实现上面的接口。
参考代码:
public class JobFullTextServiceImpl implements JobFullTextService
@Override
public void add(JobDetail jobDetail)
@Override
public void update(JobDetail jobDetail)
@Override
public JobDetail findById(long id)
return null;
@Override
public boolean deleteById(long id)
return false;
@Override
public List<JobDetail> searchByKeywords(String keywords)
return null;
@Override
public Map<String, Object> searchByPage(String keywords, int pageNum, int pageSize)
return null;
@Override
public Map<String, Object> searchByScrollPage(String keywords, String scrollId, int pageSize)
return null;
2 添加职位数据
2.1 初始化客户端连接
- 使用RestHighLevelClient构建客户端连接。
- 基于RestClient.builder方法来构建RestClientBuilder
- 用HttpHost来添加ES的节点
参考代码:
private RestHighLevelClient restHighLevelClient;
private static final String JOB_IDX_NAME = "job_idx";
public JobFullTextServiceImpl()
restHighLevelClient = new RestHighLevelClient(RestClient.builder(
new HttpHost("node1.cn", 9200, "http")
, new HttpHost("node2.cn", 9200, "http")
, new HttpHost("node3.cn", 9200, "http")
));
2.2 实现关闭客户端连接
@Override
public void close()
try
restHighLevelClient.close();
catch (IOException e)
e.printStackTrace();
2.3 编写代码实现新增职位数据
实现步骤:
- 构建IndexRequest对象,用来描述ES发起请求的数据。
- 设置文档ID。
- 使用FastJSON将实体类对象转换为JSON。
- 使用IndexRequest.source方法设置文档数据,并设置请求的数据为JSON格式。
- 使用ES High level client调用index方法发起请求,将一个文档添加到索引中。
参考代码:
@Override
public void add(JobDetail jobDetail)
// 1. 构建IndexRequest对象,用来描述ES发起请求的数据。
IndexRequest indexRequest = new IndexRequest(JOB_IDX_NAME);
// 2. 设置文档ID。
indexRequest.id(jobDetail.getId() + "");
// 3. 构建一个实体类对象,并使用FastJSON将实体类对象转换为JSON。
String json = JSON.toJSONString(jobDetail);
// 4. 使用IndexRequest.source方法设置请求数据。
indexRequest.source(json);
try
// 5. 使用ES High level client调用index方法发起请求
restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
catch (IOException e)
e.printStackTrace();
System.out.println("索引创建成功!");
常见错误:
java.lang.IllegalArgumentException: The number of object passed must be even but was [1]
at org.elasticsearch.action.index.IndexRequest.source(IndexRequest.java:474)
at org.elasticsearch.action.index.IndexRequest.source(IndexRequest.java:461)
原因:IndexRequest.source要求传递偶数个的参数,但只传递了1个
2.4 编写测试用例测试添加方法
- 在 test/java 目录中创建一个 cn.itcast.elasticsearch.service 包。
- 在cn.itcast.elasticsearch.service 包下创建一个JobFullTextServiceTest类。
- 在@BeforeTest中构建JobFullTextService对象,@AfterTest中调用close方法关闭连接。
- 编写测试用例,构建一个测试用的实体类,测试add方法。
参考代码:
public class JobFullTextServiceTest
private JobFullTextService jobFullTextService;
@BeforeTest
public void beforeTest()
jobFullTextService = new JobFullTextServiceImpl();
@Test
public void addTest()
// 1. 测试新增索引文档
jobFullTextService = new JobFullTextServiceImpl();
JobDetail jobDetail = new JobDetail();
jobDetail.setId(1);
jobDetail.setArea("山东省");
jobDetail.setCmp("山东大学");
jobDetail.setEdu("本科及以上");
jobDetail.setExp("五年工作经验");
jobDetail.setTitle("大数据工程师");
jobDetail.setJob_type("全职");
jobDetail.setPv("1700次浏览");
jobDetail.setJd("会Hadoop就行");
jobDetail.setSalary("15k-19k/月");
jobFullTextService.add(jobDetail);
@AfterTest
public void afterTest()
jobFullTextService.close();
3 根据ID检索指定职位数据
3.1 实现步骤
- 构建GetRequest请求。
- 使用RestHighLevelClient.get发送GetRequest请求,并获取到ES服务器的响应。
- 将ES响应的数据转换为JSON字符串
- 并使用FastJSON将JSON字符串转换为JobDetail类对象
- 记得:单独设置ID
参考代码:
@Override
public JobDetail findById(long id) throws IOException
// 1. 构建GetRequest请求。
GetRequest getRequest = new GetRequest(JOB_IDX_NAME, id + "");
// 2. 使用RestHighLevelClient.get发送GetRequest请求,并获取到ES服务器的响应。
GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
// 3. 将ES响应的数据转换为JSON字符串
String json = response.getSourceAsString();
// 4. 并使用FastJSON将JSON字符串转换为JobDetail类对象
JobDetail jobDetail = JSONObject.parseObject(json, JobDetail.class);
// 5. 设置ID字段
jobDetail.setId(id);
return jobDetail;
3.2 编写测试用例
参考代码:
@Test
public void findByIdTest() throws IOException
JobDetail jobDetail = jobFullTextService.findById(1);
System.out.println(jobDetail);
4 修改职位
4.1 实现步骤
- 判断对应ID的文档是否存在
a) 构建GetRequest
b) 执行client的exists方法,发起请求,判断是否存在 - 构建UpdateRequest请求
- 设置UpdateRequest的文档,并配置为JSON格式
- 执行client发起update请求
参考代码:
@Override
public void update(JobDetail jobDetail) throws IOException
// 1. 判断对应ID的文档是否存在
// a) 构建GetRequest
GetRequest getRequest = new GetRequest(JOB_IDX_NAME, jobDetai以上是关于Elasticsearch常用Java API编程的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch5.0 Java Api -- 常用DSL查询
Elasticsearch java api 常用查询方法QueryBuilder构造举例