前言
之前研究很久elk的原理和Kibana的dsl語句,但是實(shí)際運(yùn)用時(shí)候還是需要使用java的api,所以開始學(xué)習(xí)java API
官方API文檔地址:https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-api.html
5.4中文官方文檔:http://cwiki.apachecn.org/pages/viewpage.action?pageId=4260364
文章項(xiàng)目源碼地址:https://gitee.com/lwydyby/java-elk
一.準(zhǔn)備工作:
1.安裝elk三件套(這個(gè)自行百度,不是重點(diǎn))
2.搭建maven項(xiàng)目(這里使用spring boot2.0搭建項(xiàng)目):
pom文件:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.3.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
注:這里使用elasticsearch-rest-high-level-client,因?yàn)楣俜轿臋n中說之前的版本會在7.0放 棄使用,所以直接選擇這個(gè)版本學(xué)習(xí)。雖然spring boot自身存在version,但是并不是最新的 6.3.0故需要單獨(dú)配置
3.配置RestHighLevelClient:
注:這里只配置最基礎(chǔ)的,如果配置集群請自己查看官方文檔
@Bean
public RestHighLevelClient restHighLevelClient(){
return new RestHighLevelClient(
RestClient.builder(
new HttpHost(elkUrl, elkPort, "http")));
}
二.開始編寫調(diào)用方法
1.Index API
1).初始化IndexRequest(id不填寫則自動生成),拼裝要保存文檔的json串,官方給了4種方式,我這里使用第二種:



2).進(jìn)行其他額外配置,如路由,父子關(guān)系,超時(shí)時(shí)間等,具體使用見文檔
3).發(fā)送請求,這里提供了同步和異步兩種方式,我這里使用的同步請求
具體方法代碼:
/**
* 存入Object至elasticsearch
* @param o 存入對象
* @param index 索引名稱
* @param type 類型名稱
* @param id 對象id,null則自動生成
* @return
*/
public IndexResponse insertObject(Object o, String index, String type, String id) {
IndexRequest request = null;
/* id為空則自動生成*/
if (id == null) {
request = new IndexRequest(index, type);
} else {
request = new IndexRequest(index, type, id);
}
Field[] f = o.getClass().getDeclaredFields();
Map<String, Object> jsonMap = new HashMap<>();
try {
Field.setAccessible(f,true);
for (Field field : f) {
String name = field.getName();
if (name.equals("id")) {
if (field.get(o) != null) {
String ids= (String) field.get(o);
request = new IndexRequest(index, type, ids);
}
}else {
jsonMap.put(name,field.get(o));
}
}
} catch (IllegalAccessException e) {
logger.error("存入對象解析失敗:", e);
}
request.timeout(TimeValue.timeValueSeconds(5));
request.timeout("5s");
request.source(jsonMap);
try {
return client.index(request);
} catch (IOException e) {
logger.error("存入elk失敗:", e);
}
return null;
}
2.Get API
1)初始化GetRequest ,這里只能通過id進(jìn)行具體查詢,搜索功能在后邊的search API中
2).配置其他額外要求,如配置需要的字段:

3).同樣兩種請求方式
方法:
/**
* 獲取index值 必須已知id
* @param index 索引值
* @param type 類型
* @param id id
* @param c 封裝的對象class
*/
public Object getObject(String index, String type, String id, Class c) {
GetRequest request = null;
if (type == null || id == null) {
request = new GetRequest(index);
} else {
request = new GetRequest(index, type, id);
}
String[] includes = new String[c.getDeclaredFields().length];
String[] excludes = Strings.EMPTY_ARRAY;
int i=0;
Field [] f=c.getDeclaredFields();
Field.setAccessible(f,false);
for(Field field:f){
String name = field.getName();
if (!name.equals("id")) {
includes[i++]=name;
}
}
FetchSourceContext fetchSourceContext =
new FetchSourceContext(true, includes, excludes);
request.fetchSourceContext(fetchSourceContext);
try {
GetResponse getResponse = client.get(request);
String ids=getResponse.getId();
String sourceAsString = getResponse.getSourceAsString();
logger.info("獲取到的信息:"+sourceAsString);
Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
Object obj = null;
try {
obj = c.newInstance();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-mm-dd");
Field idfield=c.getDeclaredField("id");
idfield.setAccessible(true);
idfield.set(obj,ids);
for (String in : sourceAsMap.keySet()) {
Object str = sourceAsMap.get(in);
for(Field field:f){
field.setAccessible(true);
String name = field.getName();
if (name.equals(in)) {
if(name.contains("dt")){
field.set(obj,sdf.parse((String) str));
}else{
field.set(obj,str);
}
}
}
}
} catch (InstantiationException | IllegalAccessException e) {
logger.error("解析失敗:",e);
} catch (ParseException e) {
logger.error("日期解析失敗",e);
} catch (NoSuchFieldException e) {
logger.error("解析id失敗:",e);
}
return obj;
} catch (IOException e) {
logger.error("Get查詢失敗", e);
}
return null;
}
3.Exists API(太簡單了,直接上代碼)
/**
* 判斷索引下是否存在該id的信息
* @param index 索引名稱
* @param type 類型
* @param id id
* @return
*/
public boolean existsObject(String index,String type,String id){
GetRequest getRequest = new GetRequest(index, type, id);
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
try {
return client.exists(getRequest);
} catch (IOException e) {
logger.error("Get查詢失敗", e);
}
return false;
}
4.Delete Api(這里可以單一id刪除,也可以刪除所有)
/**
* 刪除某索引
* @param index
* @param type
* @param id id為null則為刪除整個(gè)索引
*/
public boolean deleteObject(String index,String type,String id){
DeleteRequest request =null;
if(id==null){
request=new DeleteRequest(index);
}else {
request = new DeleteRequest(index, type, id);
}
try {
DeleteResponse deleteResponse = client.delete(request);
ReplicationResponse.ShardInfo shardInfo = deleteResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
logger.info("存在部分未刪除成功");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();
logger.info("刪除失敗的原因:"+reason);
return false;
}
}
} catch (IOException e) {
logger.error("刪除失敗:", e);
return false;
}
return true;
}
5.update Api(其實(shí)和insert差不多)
其余操作和insert差不多,但是update支持存在則更新不存在則插入的功能

具體代碼:
/**
* 更新對象
* @param o
* @param index
* @param type
*/
public void updateObject(Object o, String index, String type) {
UpdateRequest request = null;
Field[] f = o.getClass().getDeclaredFields();
Map<String, Object> jsonMap = new HashMap<>();
try {
Field.setAccessible(f,true);
for (Field field : f) {
String name = field.getName();
if (name.equals("id")) {
String ids= (String) field.get(o);
request = new UpdateRequest(index, type, ids);
}else {
jsonMap.put(name,field.get(o));
}
}
jsonMap.put("updated",new Date());
} catch (IllegalAccessException e) {
logger.error("存入對象解析失敗:", e);
}
if(request==null){
throw new RuntimeException("object中未找到id");
}
request.docAsUpsert(true);
request.doc(jsonMap);
try {
client.update(request);
} catch (IOException e) {
logger.error("更新失敗:", e);
}
}
- bulk Api-批處理
沒什么特殊的就是把之前的單一操作改為統(tǒng)一提交
/**
* 批處理,這里只做刪除批處理
* @param index
* @param type
* @param list
*/
public void bulkDelete(String index, String type, List<String>list){
BulkRequest request = new BulkRequest();
for(String id:list){
request.add(new DeleteRequest(index,type,id));
}
try {
client.bulk(request);
} catch (IOException e) {
logger.error("批量刪除失敗:", e);
}
}
7.查詢索引下所有文檔(不屬于Documents-Api,但為了包含增刪改查所有功能寫在這)
/**
* 獲取Index下所有的內(nèi)容(為search api方法,但為了提供全額查詢功能寫在這里)
* @param index
* @param type
* @param c
* @throws Exception
*/
public List<Object> getAll(String index,String type,Class c) throws Exception {
try {
List<Object> objects=new ArrayList<>();
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.types(type);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
Object obj= MaptoObject.map2Object(sourceAsMap,Book.class,hit.getId());
objects.add(obj);
}
return objects;
} catch (IOException e) {
logger.error("查詢所有失敗",e);
}
return null;
}
今天就看到這,有時(shí)間繼續(xù)更新....................