前言
java操作es的api
一、集成SpringBoot
找官方文档 (7.6.x)
https://www.elastic.co/guide/index.html
1. 找到原生的依赖。
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.2</version>
</dependency>
2. 找对象。
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
3. 分析这个类的方法。
类中的方法api
二、集成SpringBoot代码实现(7.6.1)
1.导入依赖
<!--整合es-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!--es-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.1</version>
</dependency>
2.配置ElasticSearch
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ElasticSearchClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")));
return client;
}
}
3.导入bean后,使用。
@SpringBootTest
class ElasticSearchApiApplicationTests {
@Autowired
private RestHighLevelClient restHighLevelClient;
}
三 、具体的api测试
1、创建索引
// 测试索引的创建
@Test
void testCreateIndex() throws IOException {
// 1.创建索引请求
CreateIndexRequest request = new CreateIndexRequest("kuang_index");
// 2.执行创建请求,请求后获得响应createIndexResponse
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse);
}
2、判断索引是否存在
// 测试获取索引,只能判断其是否存在
@Test
void testExistIndex() throws IOException {
// 1.创建索引请求
GetIndexRequest request = new GetIndexRequest("kuang_index");
// 2.获取索引,是否存在
boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
3、删除索引
// 测试删除索引
@Test
void testDeleteIndex() throws IOException {
// 1.创建删除索引请求
DeleteIndexRequest request = new DeleteIndexRequest("kuang_index");
// 2.获取删除状态
AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
4、添加文档
// 测试添加文档
@Test
void testAddDocument() throws IOException {
// 1.创建对象
User user = new User("狂神说",3);
// 2.创建请求
IndexRequest request = new IndexRequest("kuang_index");
// 3.规则 put /kuang_index/_doc/1
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));// 或者 request.timeout("1s");
// 4.把数据放入请求 json
IndexRequest source = request.source(JSON.toJSONString(user), XContentType.JSON);
// 5.客户端发送请求,获取响应结果
IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());// 结果的json
System.out.println(indexResponse.status());// 对应我们命令返回的状态 created
}
5、判断文档是否存在
// 获取文档信息,判断是否存在 get /index/_doc/1
@Test
void testIsExists() throws IOException {
GetRequest getRequest = new GetRequest("kuang_index", "1");
// 不获取返回_source的上下文了
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);
}
6、获取文档的信息
// 获取文档的信息
@Test
void testGetDocument() throws IOException {
GetRequest getRequest = new GetRequest("kuang_index", "1");
GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
System.out.println(getResponse.getSourceAsString());// 打印文档的内容
System.out.println(getResponse);// 返回的全部内容和密令一样
}
7、更新文档的信息
// 更新文档的信息
@Test
void testUpdateDocument() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("kuang_index", "1");
updateRequest.timeout("1s");
User user = new User("狂神说Java", 18);
updateRequest.doc(JSON.toJSONString(user),XContentType.JSON);
UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(update.status());
}
8、删除文档信息
// 删除文档记录
@Test
void testDeleteRequest() throws IOException {
DeleteRequest deleteRequest = new DeleteRequest("kuang_index","1");
deleteRequest.timeout("1s");
DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(deleteResponse.status());
}
9、批量插入数据
特殊的,真实的项目一般都会批量插入数据。
// 特殊的,真实的项目一般都会批量插入数据
@Test
void testBulkRequest() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("1s");
ArrayList<User> users = new ArrayList<>();
users.add(new User("kuangshen1",3));
users.add(new User("kuangshen2",3));
users.add(new User("kuangshen3",3));
users.add(new User("qinjiang1",3));
users.add(new User("qinjiang1",3));
users.add(new User("qinjiang1",3));
for (int i = 0; i < users.size(); i++) {
bulkRequest.add(new IndexRequest("kuang_index")
.id(""+(i+1))// 不设置id,则会生成默认id
.source(JSON.toJSONString(users.get(i)),XContentType.JSON));
}
BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulkResponse.hasFailures());// 是否失败,返回false代表成功
}
10、查询
// 查询
// SearchRequest 搜索请求
// SearchSourceBuilder 条件构造
// HighlightBuilder 构建高亮
// TermQueryBuilder精确查询
// MatchALLQueryBuilder
// xxx QueryBuilder 对应我们刚才看到的命令!
@Test
void testSearch() throws IOException {
// 创建请求
SearchRequest searchRequest = new SearchRequest("kuang_index");
// 构建搜索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 查询条件,我们可以使用 QueryBuilders 工具来实现
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "qinjiang1");// 精确
//MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();// 匹配所有
sourceBuilder.query(termQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(searchResponse.getHits()));
System.out.println("=============");
for (SearchHit hit : searchResponse.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
}
11、分组嵌套查询
字段及类型为:
projectCode:String
interfaceKey:String
applyDate:Date
实现sql语句:select projectCode, interfaceKey, applyDate, count(1) as count from tableName group by projectCode,interfaceKey,applyDate
@Test
void testSearch() throws Exception {
SearchRequest searchRequest = new SearchRequest("xxx_index");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//最外层设置为0,表示不返回具体的数据
searchSourceBuilder.size(0);
/**
* 聚合查询条件
*/
AggregationBuilder projectAggBuilder = AggregationBuilders.terms("projectCode_count").field("projectCode").size(Integer.MAX_VALUE);
AggregationBuilder interfaceAggBuilder = AggregationBuilders.terms("interfaceKey_count").field("interfaceKey").size(Integer.MAX_VALUE);
//date类型进行group by
AggregationBuilder requestTimeAggBuilder = AggregationBuilders.dateHistogram("requestTime_count").field("requestTime")
.calendarInterval(DateHistogramInterval.DAY).format("yyyy-MM-dd");
/**
* 范围查询, group by之前先用where条件进行过滤
*/
// fromDayDate=-x:表示查询x天前的数据
String fromDayDate = DateUtil.getDayDateStr(-2);
String toDayDate = DateUtil.getDayDateStr(0);
searchSourceBuilder.query(QueryBuilders.rangeQuery("requestTime").gte(fromDayDate).lt(toDayDate));
//生成嵌套聚合对象
searchSourceBuilder.aggregation(projectAggBuilder.subAggregation(interfaceAggBuilder.subAggregation(requestTimeAggBuilder)));
searchRequest.source(searchSourceBuilder);
//获得查询结果对象
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
List<Aggregation> aggregationList = aggregations.asList();
/**
* 对结果进行解析并生产DO对象,虽然有6层for循环,但是4层的循环长度都是1
*/
List<InterfaceApplyStatistics> applyStatisticsList = new ArrayList<>();
for (Aggregation aggregation : aggregationList) {
List<? extends Terms.Bucket> projectBuckets = ((ParsedStringTerms) aggregation).getBuckets();
for (Terms.Bucket projectBucket : projectBuckets) {
Object projectCode = projectBucket.getKey();
Aggregations bucketAggregations = projectBucket.getAggregations();
for (Aggregation bucketAggregation : bucketAggregations) {
List<? extends Terms.Bucket> interfaceBuckets = ((ParsedStringTerms) bucketAggregation).getBuckets();
for (Terms.Bucket interfaceBucket : interfaceBuckets) {
Object interfaceKey = interfaceBucket.getKey();
Aggregations applyDateAggregations = interfaceBucket.getAggregations();
for (Aggregation applyDateAggregation : applyDateAggregations) {
List<? extends Histogram.Bucket> applyDateBuckets = ((ParsedDateHistogram) applyDateAggregation).getBuckets();
for (Histogram.Bucket applyDateBucket : applyDateBuckets) {
Object applyDate = applyDateBucket.getKey();
long docCount = applyDateBucket.getDocCount();
InterfaceApplyStatistics applyStatistics = new InterfaceApplyStatistics();
applyStatistics.setProjectKey(projectCode.toString());
applyStatistics.setApiKey(interfaceKey.toString());
applyStatistics.setApplyCount(docCount);
try {
applyStatistics.setApplyDate(DateUtil.str2Date2(applyDate.toString()));
} catch (ParseException e) {
log.error("字符串日期解析为Date出错:{}", fromDayDate, e);
throw e;
}
if (!ObjectUtils.isEmpty(applyStatistics.getApiKey()) && !ObjectUtils.isEmpty(applyStatistics.getApiKey())) {
applyStatisticsList.add(applyStatistics);
}
}
}
}
}
}
}
/**
* 按照时间的正序排列
*/
applyStatisticsList.sort((a, b) -> {
return a.getApplyDate().compareTo(b.getApplyDate());
});
//System.out.println(applyStatisticsList);
//插入数据库操作代码省略...
}
@Data
@TableName("interface_apply_statistics")
public class InterfaceApplyStatistics {
/**
* 系统编码
*/
@TableField("project_key")
private String projectKey;
/**
* 接口编码
*/
@TableField("api_key")
private String apiKey;
/**
* 调用时间
*/
@TableField("apply_date")
private Date applyDate;
/**
* 调用次数
*/
@TableField("apply_count")
private Long applyCount;
/**
* 调用返回条数
*/
@TableField("apply_result_size")
private Long applyResultSize;
}
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
private static final String dateFormat2 = "yyyy-MM-dd";
/**
* 日期转为字符串
*/
public static String date2Str(Date date) {
SimpleDateFormat format = new SimpleDateFormat(dateFormat);
return format.format(date);
}
/**
* 日期转为字符串
*/
public static String date2Str2(Date date) {
SimpleDateFormat format = new SimpleDateFormat(dateFormat2);
return format.format(date);
}
/**
* 字符串转为日期
*/
public static Date str2Date(String dateStr) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat(dateFormat);
return format.parse(dateStr);
}
/**
* 字符串转为日期
*/
public static Date str2Date2(String dateStr) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat(dateFormat2);
return format.parse(dateStr);
}
public static String getDayDateStr(int days) {
String beforeOneDayDate;
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.DAY_OF_MONTH, days);
beforeOneDayDate = DateUtil.date2Str2(calendar.getTime());
return beforeOneDayDate;
}
}