ElasticSearch】java操作ElasticSearch 7.x
ElasticSearch7.x中不在建议使用transport,并且将在8.0彻底淘汰。
所以我们需要使用7.x推荐使用的RestHighLevelClient来操作ElasticSearch。
在springboot项目中我们配置RestHighLevelClient对象时可以通过配置文件application.yml
spring:
elasticsearch:
rest:
connection-timeout: 1000
uris: http://localhost:9200
当然我们也可以通过代码实例化:
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("127.0.0.1",9200,"http"))
);
return restHighLevelClient;
}
1. 导入依赖
<?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>com.siyi</groupId>
<artifactId>ElasticSearchDemo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
</dependencies>
</project>
2. 操作索引
@RunWith(SpringRunner.class)
@SpringBootTest
public class ESTest {
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 创建索引
* @throws IOException
*/
@Test
public void testCreateIndex() throws IOException {
//1. 创建索引请求
CreateIndexRequest request = new CreateIndexRequest("siyi");
//2. 客户端执行请求 IndicesClient,请求后获得响应
CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
//输出是否创建成功
System.out.println(response.isAcknowledged());
}
/**
* 查询是否存在索引
* @throws IOException
*/
@Test
public void testExistIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("siyi");
boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
/**
* 删除索引
*/
@Test
public void testDeleteIndex() throws IOException {
//创建删除索引请求对象
DeleteIndexRequest request = new DeleteIndexRequest("siyi");
//客户端执行请求
AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
//输出是否删除成功
System.out.println(response.isAcknowledged());
}
3. 操作文档
3.1 新增文档
/**
* 添加文档
*/
@Test
public void addDocument() throws IOException {
//获取对象
Goods goods = goodsDao.findById(12991976L);
//创建请求
IndexRequest request = new IndexRequest("siyi");
//规则 put /siyi/_doc/1
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));
//将我们的数据放入请求
request.source(JSON.toJSONString(goods), XContentType.JSON);
//客户端发送请求
IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
//IndexResponse[index=siyi,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
System.out.println(response);
//响应状态 CREATED
System.out.println(response.status());
}
3.2 删除文档
/**
* 删除文档
* @throws IOException
*/
@Test
public void testDeleteDocument() throws IOException {
DeleteRequest request = new DeleteRequest("siyi","1");
request.timeout("1s");
DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
//DeleteResponse[index=siyi,type=_doc,id=1,version=3,result=deleted,shards=ShardInfo{total=2, successful=1, failures=[]}]
System.out.println(response);
//OK
System.out.println(response.status());
}
3.3 修改文档
@Test
public void testUpdateDocument() throws IOException {
UpdateRequest request = new UpdateRequest("siyi","1");
request.timeout("1s");
Goods goods = goodsDao.findById(12991976L);
goods.setTitle("xxxx");
request.doc(JSON.toJSONString(goods),XContentType.JSON);
UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
//UpdateResponse[index=siyi,type=_doc,id=1,version=2,seqNo=1,primaryTerm=1,result=updated,shards=ShardInfo{total=2, successful=1, failures=[]}]
System.out.println(response);
System.out.println(response.status());
}
3.4 批量增,删,改文档
/**
* 批量新增文档
*/
@Test
public void testBulkRequest() throws IOException {
BulkRequest request = new BulkRequest();
request.timeout("1s");
List<Goods> list = goodsDao.findAll();
list.forEach(goods -> {
//批量更新或者删除只需修改方法即可
request.add(new IndexRequest("siyi")
.id(""+goods.getId())
.source(JSON.toJSONString(goods),XContentType.JSON));
});
BulkResponse responses = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
System.out.println(responses);
//是否删除失败 返回false代表删除成功 false
System.out.println(responses.hasFailures());
}
当我们需要使用批量增删改数据时,只需要使用BulkRequest的add,delete,update中相应方法即可。
3.5 查询文档
3.5.1 基本查询
/**
* 获取文档,判断是否存在 get /index/doc/1
*/
@Test
public void testIsExists() throws IOException {
GetRequest request = new GetRequest("siyi","1");
//不获取返回的 _source的上下文了
request.fetchSourceContext(new FetchSourceContext(false));
request.storedFields("_none");
boolean exists = restHighLevelClient.exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
/**
* 获取文档信息
* @throws IOException
*/
@Test
public void testGetDocument() throws IOException {
GetRequest request = new GetRequest("siyi","1");
GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
System.out.println(response.getSourceAsString());
System.out.println(response);
}
3.5.2 复杂查询
/**
* 查询
*/
@Test
public void testSearch() throws IOException {
SearchRequest request = new SearchRequest("siyi");
//构建搜索条件
SearchSourceBuilder builder = new SearchSourceBuilder();
//查询条件,我们可以使用QueryBuilders工具来实现
//QueryBuilders.matchAllQuery() 匹配所有
//QueryBuilders.termQuery() 精确匹配
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "java");
builder.query(termQueryBuilder);
builder.timeout(new TimeValue(60, TimeUnit.SECONDS));
request.source(builder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(response.getHits()));
System.out.println("----------------------");
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
}
当然,我们可以向直接操作ElasticSearch一样去构建查询条件。
在java中有对应的类来实现我们需要构造的查询条件。
3.5.3 分页查询
/**
* 查询
*/
@Test
public void testSearch() throws IOException {
SearchRequest request = new SearchRequest("siyi");
//构建搜索条件
SearchSourceBuilder builder = new SearchSourceBuilder();
//查询条件,我们可以使用QueryBuilders工具来实现
//QueryBuilders.matchAllQuery() 匹配所有
//QueryBuilders.termQuery() 精确匹配
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "java");
builder.query(termQueryBuilder);
builder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//分页查询,第0页 每页30
builder.from(0);
builder.size(30);
request.source(builder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(response.getHits()));
System.out.println("----------------------");
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
}
3.5.4 查询结果高亮显示
/**
* 查询
*/
@Test
public void testSearch() throws IOException {
SearchRequest request = new SearchRequest("siyi");
//构建搜索条件
SearchSourceBuilder builder = new SearchSourceBuilder();
//查询条件,我们可以使用QueryBuilders工具来实现
//QueryBuilders.matchAllQuery() 匹配所有
//QueryBuilders.termQuery() 精确匹配
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "java");
builder.query(termQueryBuilder);
builder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//分页查询,第0页 每页30
builder.from(0);
builder.size(30);
//设置高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
//高亮显示的字段
highlightBuilder.field("title");
highlightBuilder.preTags("<em>");
highlightBuilder.postTags("</em>");
builder.highlighter(highlightBuilder);
request.source(builder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(response.getHits()));
System.out.println("----------------------");
for (SearchHit hit : response.getHits().getHits()) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
System.out.println(sourceAsMap);
//输出高亮情况
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField highlightField = highlightFields.get("title");
if(highlightField == null) continue;
Text[] fragments = highlightField.getFragments();
String title = "";
for (Text fragment : fragments) {
title += fragment;
}
//使用有高亮的结果替换原本的结果,
sourceAsMap.put("title",title);
System.out.println(sourceAsMap);
}
}