第十章 ES与Spring的集成

  • Post author:
  • Post category:其他





一、




综述






1、常见的




Elasticsearch Java API




有四类




client




连接方式:






1.1、




TransportClient




(不推荐)



Elasticsearch原生的api,TransportClient可以支持2.x,5.x版本,TransportClient 将会在Elasticsearch 7.0弃用并在8.0中完成删除。




1.2、




RestClient









ES




官方推荐使用






1.3、




Jest




(不推荐)



是Java社区开发的,是Elasticsearch的Java Http Rest客户端。




1.4、




Spring Data Elasticsearch



与Spring生态对接,可以在web系统中整合到Spring中使用,与SpringBoot、SpringData版本容易冲突,而且往往很难跟上Elasticsearch版本的更新,比如SpringBoot目前的2.3.1.RELEASE,所支持Elasticsearch 7.6.2。

从使用上来说,Spring Data的使命是给各种数据访问提供统一的编程接口,不管是关系型数据库(如 MySQL),还是非关系数据库(如Redis),或者类似Elasticsearch这样的索引数据库。从而简化开发人员的代码,提高开发效率,也就是说,Spring Data想要把对任何数据的访问都抽象为类似接口,这就导致了 Spring Data Elasticsearch在基本查询上没问题,但是复杂查询(模糊、通配符、match查询、聚集查询等)就显得力不从心了,此时,我们还是只能使用原生查询。




2、REST Client介绍



Java REST Client有


Low Level和High Level


两种:



Java Low Level REST Client:

使用该客户端需要将HTTP请求的body手动拼成JSON格式,HTTP响应也必须将返回的JSON数据手动封装成对象,使用上更为原始。



Java High Level REST Client:

该客户端基于Low Level客户端实现,提供API解决Low Level客户端需要手动转换数据格式的问题。

ES的官网已经提供了非常详尽的API参考手册,参见:





https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html






二、




REST Client使用






1、




Java Low Level REST Client



具体代码在模块es-low-level模块下




1.1、maven导入




<


dependencies


>



<


dependency


>



<


groupId


>org.elasticsearch.client</


groupId


>



<


artifactId


>elasticsearch-rest-client</


artifactId


>



<


version


>7.7.0</


version


>



</


dependency


>



</


dependencies


>




1.




2、配置访问




es




的请求




Map<String,String> params = Collections.EMPTY_MAP;



String jsonString =


“{”


+





\”


msg


\”


:


\”


Java Low Level REST Client


\”





+


“}”


;



System.out.println(jsonString);



HttpEntity entity =


new


NStringEntity(jsonString, ContentType.APPLICATION_JSON);



Request request =


new


Request(


“PUT”


,


“enjoy_test/_doc/6”


);



request.addParameters(params);



request.setEntity(entity);




1.




3、发送请求并接收应答




Response response = restClient.performRequest(request);



System.out.println(response);



System.out.println(EntityUtils.toByteArray(response.getEntity()));

因为Java Low Level REST Client用法比较原始,在实际工作中用的比较少所以大概了解下用法即可,对应的类是TestEsLowSdk。




2、




Java High Level REST Client



具体代码在模块es-high-level模块下




2.1、maven依赖导入




<


dependency


>



<


groupId


>org.elasticsearch.client</


groupId


>



<


artifactId


>elasticsearch-rest-high-level-client</


artifactId


>



<


version


>7.7.0</


version


>



</


dependency


>

代码对应的类是 TestEsHighSdk




2.2




、创建访问客户端




RestClientBuilder restClientBuilder = RestClient.builder(


new


HttpHost(





192


.


168


.


0


.1


01





,


9200


,


“http”


));




2




.3




、创建索引






/*创建索引*/





CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);





/* 这里可以对索引对象进行属性设置 */







createIndexRequest.settings(Settings.builder()







.put(






“index.number_of_shards”






,






3






)







.put(






“index.codec”






,






“best_compression”






));







Map<String,Object> message =






new






HashMap<>();







message.put(






“type”






,






“text”






);







Map<String,Object> properties =






new






HashMap<>();







properties.put(






“message”






,message);







Map<String,Object> mapping =






new






HashMap<>();







mapping.put(






“properties”






,properties);







createIndexRequest.mapping(mapping);







createIndexRequest.mapping(






“{”






+













\”






msg






\”






:






\”






Java Low Level REST Client






\”













+






“}”






, XContentType.JSON);







XContentBuilder.builder()





//



CreateIndexResponse createIndexResponse



= restHighLevelClient.indices().create(createIndexRequest,RequestOptions.DEFAULT);



System.out.println(createIndexResponse.index());



System.out.println(createIndexResponse.isAcknowledged());

使用CreateIndexRequest进行索引创建,如果想要对索引进行静态配置,可以使用

request.settings

。配置索引的映射有好几种方式,比如我们想配置的索引映射是:

put /high_sdk/_mapping

{

“properties”: {

” message”: {

“type”: “text”

}

}

}



可以采用:

request.mapping(


“{\n” + ” \”properties\”: {\n” +” \”message\”: {\n” + ” \”type\”: \”text\”\n” + ” }\n” + ” }\n” + “}”,

XContentType.JSON);



也可以采用:

Map<String, Object> message = new HashMap<>();

message.put(“type”, “text”);

Map<String, Object> properties = new HashMap<>();

properties.put(“message”, message);

Map<String, Object> mapping = new HashMap<>();

mapping.put(“properties”, properties);

request.mapping(mapping);



还可以采用:

XContentBuilder builder = XContentFactory.jsonBuilder();

builder.startObject();

{ builder.startObject(“properties”);

{ builder.startObject(“message”);

{ builder.field(“type”, “text”);}

builder.endObject();

}

builder.endObject();

}

builder.endObject();

request.mapping(builder);

然后通过client.indices().create方法将请求发送给es即可,es的应答将通过CreateIndexResponse返回给我们。




2.4




、索引




(




保存




)




文档



基本上和创建索引的思路是一样的




/*索引(保存)文档*/





IndexRequest indexRequest


=


new


IndexRequest(


indexName


);



indexRequest


.id(


docId


);

使用IndexRequest进行文档的索引,相关的请求体可以通过多种方法生成


XContentBuilder xContentBuilder


=


XContentFactory


.




jsonBuilder




();



xContentBuilder


.startObject();



{




xContentBuilder


.field(


“user”


,





hankin





);



xContentBuilder


.timeField(


“postData”


,


new


Date());



xContentBuilder


.field(


“message”


,


“Go ELK”


);



}



xContentBuilder


.endObject();



indexRequest


.source(


xContentBuilder


);



IndexResponse index


=


restHighLevelClient


.index(


indexRequest


,


RequestOptions


.




DEFAULT




);



System


.




out




.println(


index


.getIndex());



System


.




out




.println(


index


.getId());

然后通过client.index方法将请求发送给es即可,es的应答将通过CreateIndexResponse返回给我们。




2.5




、查询文档



使用GetRequest进行查询,通过client.get方法将请求发送给es即可,es的应答将通过GetResponse返回给我们。




/*查询文档*/





GetRequest getRequest


=


new


GetRequest(


indexName


,


docId


);



GetResponse getResponse


=


restHighLevelClient


.get(


getRequest


,


RequestOptions


.




DEFAULT




);



System


.




out




.println(


” get indexname = ”


+


getResponse


.getIndex());



if


(


getResponse


.isExists()){




System


.




out




.println(


“获取的文档:”


+


getResponse


.getSourceAsString());



}


else


{




System


.




out




.println(


“文档不存在”


);



}

更多的与检索相关的类或者方法,我们将在和SpringBoot的集成这个章节看到。




三、




SpringBoot




集成REST Client






1、环境配置



具体代码在模块springboot-highlevel模块下:




1.1、引入maven依赖:






<!– es–>





<


dependency


>



<


groupId


>org.elasticsearch</


groupId


>



<artifactId>elasticsearch</artifactId>



<version>7.7.0</version>



</


dependency


>



<


dependency


>



<


groupId


>org.elasticsearch.client</


groupId


>



<artifactId>elasticsearch-rest-high-level-client</artifactId>



<version>7.7.0</version>



</


dependency


>

为方便我们的使用,我们还会引入一些其他的组件,比如fastjson和Swagger2:




<!– fastjson–>





<


dependency


>



<


groupId


>com.alibaba</


groupId


>



<


artifactId


>fastjson</


artifactId


>



<


version


>1.2.


69


</


version


>



</


dependency


>





<!– Swagger2 –>





<


dependency


>



<


groupId


>io.springfox</


groupId


>



<


artifactId


>springfox-swagger2</


artifactId


>



<


version


>2.


9.2


</


version


>



</


dependency


>



<


dependency


>



<


groupId


>io.springfox</


groupId


>



<


artifactId


>springfox-swagger-ui</


artifactId


>



<


version


>2.


9.2


</


version


>



</


dependency


>

比较关键的类是:

  • AggsSearch:聚集搜索服务类
  • NormalSearch:一般搜索服务类
  • OperateDoc:操作文档的服务
  • OperateIndex:操作索引的服务

SendSearchRequest:通用的发送Search请求,并处理响应结果的服务。其中主要包括了索引的管理、文档的管理、_search接口基本用法、基于词项的查询、基于全文的查询、基于全文的模糊查询、组合查询、聚集查询的相关范例,详情参阅相关代码。




1.2、添加application.yml配置




server


:



port


:


8899



elasticsearch


:



host


: 192.168.0.101



port


: 9200



配置类代码实现:


@Configuration



public class


ESConfig


{




@Value


(


“${elasticsearch.host}”


)



private


String


host


;



@Value


(


“${elasticsearch.port}”


)



private int


port


;



@Bean



public


RestClientBuilder


restClientBuilder


() {




HttpHost httpHost


=


new


HttpHost(


host


,


port


,


“http”


);



RestClientBuilder restClientBuilder


=


RestClient


.




builder




(


httpHost


);



return


restClientBuilder


;



}



@Bean



public RestHighLevelClient highLevelClient(@Autowired RestClientBuilder restClientBuilder) {




return new RestHighLevelClient(restClientBuilder);



}



}




1.3、实体类代码






/**







* 给前端页面返回的应答实体







*/





public class ResponseBean {






//状态码







private


Integer


code


;





//返回信息







private


String


message


;





//返回的数据







private


Object


data


;



public


ResponseBean


(


Integer


code,


String


message,


Object


data) {




this


.


code


= code;



this


.


message


= message;



this


.


data


= data;



}

保存文档的实体:


public class


User


{




private


String


firstName


;



private


String


secondName


;



private


String


content


;



private


Integer


age


;




1.4、启动类代码实现:




@SpringBootApplication



public class


DemoApplication


{




public static void


main


(


String


[] args) {




SpringApplication


.




run




(


DemoApplication


.


class


, args);



}



}




2、测试代码实现






2.1、controller层代码实现




@Api


(value =


“ES测试接口”


, tags = {



“ES测试接口”


})



@RestController



@RequestMapping


(


“/es”


)



@CrossOrigin


(origins =


“*”


, methods = {



RequestMethod


.




GET




,


RequestMethod


.




POST




,


RequestMethod


.




DELETE




,


RequestMethod


.




PUT




})



public class


ESController


{




@Resource



private


OperateIndex


operateIndex


;



@Resource



private


OperateDoc


operateDoc


;



@Resource



private


NormalSearch


normalSearch


;



@Resource



private


AggsSearch


aggsSearch


;



private  final


Logger


log


=


LoggerFactory


.




getLogger




(


ESConfig


.


class


);



private final static


String




KIBANA_SAMPLE_DATA_FLIGHTS




=


“kibana_sample_data_flights”


;



private final static


String




KIBANA_SAMPLE_DATA_LOGS




=


“kibana_sample_data_logs”


;



@ApiOperation


(value =


“es测试创建索引接口”


, notes =


“es测试创建索引接口”


)



@RequestMapping


(value =


“/index/creation”


, method =


RequestMethod


.




POST




)



public


ResponseBean


createIndex


(


@RequestParam


String


indexName) {




try


{




if


(


operateIndex


.createIndex(indexName)) {




return new


ResponseBean(


200


,


“创建成功”


,


null


);



}


else


{




return new


ResponseBean(


1002


,


“创建失败”


,


null


);



}



}


catch


(


IOException


e) {




e.printStackTrace();



}



return null


;



}



@ApiOperation


(value =


“es测试是否存在索引接口”


, notes =


“es测试是否存在索引接口”


)



@RequestMapping


(value =


“/index/existence”


, method =


RequestMethod


.




POST




)



public


ResponseBean


indexExists


(


@RequestParam


String


indexName) {




boolean


isExists


=


operateIndex


.isIndexExists(indexName);



String msg


=


isExists


?


“索引存在:”


+indexName :


“索引不存在:”


+indexName ;



return new


ResponseBean(


200


,


msg


,


isExists


);



}



@ApiOperation


(value =


“es测试删除索引接口”


, notes =


“es测试删除索引接口”


)



@RequestMapping


(value =


“/index/erasure”


, method =


RequestMethod


.




POST




)



public


ResponseBean


deleteIndex


(


@RequestParam


String


indexName) {




boolean


isDelete


=


operateIndex


.deleteIndex(indexName);



if


(


isDelete


) {




return new


ResponseBean(


200


,


“删除成功”


,


null


);



}


else


{




return new


ResponseBean(


10002


,


“删除失败”


,


null


);



}



}



@ApiOperation


(value =


“es测试插入文档接口”


, notes =


“es测试插入文档接口”


)



@RequestMapping


(value =


“/doc/insertion”


, method =


RequestMethod


.




POST




)



public


ResponseBean


insertDoc


(


@RequestBody


User


user,


@RequestParam


String


indexName,



@RequestParam


String


docId) {




return


operateDoc


.insertDoc(user,indexName,docId);



}



@ApiOperation


(value =


“es测试获取文档接口”


, notes =


“es测试插入文档接口”


)



@RequestMapping


(value =


“/doc/query”


, method =


RequestMethod


.




GET




)



public


ResponseBean


getDoc


(


@RequestParam


String


indexName,


@RequestParam


String


docId) {




return


operateDoc


.getDoc(indexName,docId);



}



@ApiOperation


(value =


“es测试更新文档接口”


, notes =


“es测试插入文档接口”


)



@RequestMapping


(value =


“/doc/update”


, method =


RequestMethod


.




POST




)



public


ResponseBean


updateDoc


(


@RequestParam


String


indexName,


@RequestParam


String


docId,



@RequestParam


String


fieldName,


@RequestParam


String


fieldValue) {




return


operateDoc


.updateDoc(indexName,docId,fieldName,fieldValue);



}



@ApiOperation


(value =


“es测试删除文档接口”


, notes =


“es测试插入文档接口”


)



@RequestMapping


(value =


“/doc/erasure”


, method =


RequestMethod


.




POST




)



public


ResponseBean


deleteDoc


(


@RequestParam


String


indexName,


@RequestParam


String


docId) {




return


operateDoc


.deleteDoc(indexName,docId);



}



@ApiOperation


(value =


“_search接口基本用法”


, notes =


“search接口基本用法”


)



@RequestMapping


(value =


“/search/example”


, method =


RequestMethod


.




POST




)



public


ResponseBean


searchExample


() {




return


normalSearch


.searchExample(




KIBANA_SAMPLE_DATA_FLIGHTS




);



}



@ApiOperation


(value =


“基于词项的查询”


, notes =


“基于词项的term查询”


)



@RequestMapping


(value =


“/search/term”


, method =


RequestMethod


.




POST




)



public


ResponseBean


termsBasedSearch


() {




return


normalSearch


.termsBasedSearch(




KIBANA_SAMPLE_DATA_FLIGHTS




,


“dayOfWeek”


);



}



@ApiOperation


(value =


“基于全文的查询”


, notes =


“基于全文的multi_match查询”


)



@RequestMapping


(value =


“/search/match”


, method =


RequestMethod


.




POST




)



public


ResponseBean


matchBasedSearch


() {




return


normalSearch


.matchBasedSearch(




KIBANA_SAMPLE_DATA_FLIGHTS




,



“AT”


,


“DestCountry”


,


“OriginCountry”


);



}



@ApiOperation


(value =


“基于全文的模糊查询”


, notes =


“基于全文的模糊查询”


)



@RequestMapping


(value =


“/search/fuzzy”


, method =


RequestMethod


.




POST




)



public


ResponseBean


fuzzySearch


() {




return


normalSearch


.fuzzySearch(




KIBANA_SAMPLE_DATA_LOGS




,


“message”


,


“firefix”


);



}



@ApiOperation


(value =


“组合查询范例”


, notes =


“组合查询之bool查询”


)



@RequestMapping


(value =


“/search/combination-bool”


, method =


RequestMethod


.




POST




)



public


ResponseBean


combinationSearch


() {




return


normalSearch


.boolSearch(




KIBANA_SAMPLE_DATA_LOGS




);



}



@ApiOperation


(value =


“聚集查询范例”


, notes =


“聚集查询范例”


)



@RequestMapping


(value =


“/search/aggsExample”


, method =


RequestMethod


.




POST




)



public


ResponseBean


aggsExampleSearch


() {




return


aggsSearch


.aggsExampleSearch(




KIBANA_SAMPLE_DATA_FLIGHTS




);



}



}




2.2、普通搜索业务代码实现:




@Service



public class


NormalSearch


{




@Resource



private


RestHighLevelClient


restHighLevelClient


;



@Resource



private


SendSearchRequest


sendSearchRequest


;





/**







* get kibana_sample_data_flights/_search







* {








*     “from”:100,







*     “size”:20,







*     “query”:{








*        “match_all”:{}







*        },







*     “_source”:[“Origin*”,”*Weather”],







*     “sort”:[{“DistanceKilometers”:”asc”},{“FlightNum”:”desc”}]







* }







*/







public


ResponseBean


searchExample


(


String


indexName) {




SearchRequest searchRequest


=


new


SearchRequest();



searchRequest


.indices(indexName);



SearchSourceBuilder searchSourceBuilder


=


new


SearchSourceBuilder();



searchSourceBuilder


.from(


0


);



searchSourceBuilder


.size(


5


);



searchSourceBuilder


.query(


QueryBuilders


.




matchAllQuery




());



String


[]


includeFields


=


new


String[]{



“Origin*”


,


“*Weather”


};



searchSourceBuilder


.fetchSource(


includeFields


,


null


);



searchSourceBuilder


.sort(


new


FieldSortBuilder(


“DistanceKilometers”


).order(


SortOrder


.




ASC




));



searchSourceBuilder


.sort(


new


FieldSortBuilder(


“FlightNum”


).order(


SortOrder


.




DESC




));



searchRequest


.source(


searchSourceBuilder


);



return


sendSearchRequest


.send(


searchRequest


,


RequestOptions


.




DEFAULT




);



}





/**







* get kibana_sample_data_flights/_search







* {








*     “query”:{








*        “term”:{








*           “dayOfWeek”:3







*                }*   }







* }







*/







public


ResponseBean


termsBasedSearch


(


String


indexName,


String


fieldName) {




SearchRequest searchRequest


=


new


SearchRequest();



searchRequest


.indices(indexName);



SearchSourceBuilder searchSourceBuilder


=


new


SearchSourceBuilder();





TermQueryBuilder termQueryBuilder


=


QueryBuilders


.




termQuery




(fieldName,


3


);



searchSourceBuilder


.query(


termQueryBuilder


);



searchRequest


.source(


searchSourceBuilder


);



return


sendSearchRequest


.send(


searchRequest


,


RequestOptions


.




DEFAULT




);


}





/**







* POST /kibana_sample_data_flights/_search







* {








*     “query”: {








*        “multi_match”: {








*           “query”:”AT”,







*           “fields”:[“DestCountry”, “OriginCountry”]







*                }*   }







* }







*/







public


ResponseBean


matchBasedSearch


(


String


indexName,


Object


text,


String


… fieldsName) {




SearchRequest searchRequest


=


new


SearchRequest();



searchRequest


.indices(indexName);



SearchSourceBuilder searchSourceBuilder


=


new


SearchSourceBuilder();



searchSourceBuilder


.query(


QueryBuilders


.




multiMatchQuery




(text,fieldsName));



searchRequest


.source(


searchSourceBuilder


);



return


sendSearchRequest


.send(


searchRequest


,


RequestOptions


.




DEFAULT




);



}





/**







* 基于全文的模糊查询







* get kibana_sample_data_logs/_search







* {








*     “query”: {








*         “fuzzy”: {








*             “message”: {








*                 “value”: “firefix”,







*                 “fuzziness”: “1”







*             }







*         }







*     }







* }







*/







public


ResponseBean


fuzzySearch


(


String


indexName,


String


fieldsName,


String


text) {




SearchRequest searchRequest


=


new


SearchRequest();



searchRequest


.indices(indexName);



SearchSourceBuilder searchSourceBuilder


=


new


SearchSourceBuilder();





// KIBANA_SAMPLE_DATA_LOGS, “message”,”firefix”







FuzzyQueryBuilder fuzzyQueryBuilder


=


QueryBuilders


.




fuzzyQuery




(fieldsName, text);



fuzzyQueryBuilder


.fuzziness(


Fuzziness


.




ONE




);



searchSourceBuilder


.query(


fuzzyQueryBuilder


);



searchRequest


.source(


searchSourceBuilder


);



return


sendSearchRequest


.send(


searchRequest


,


RequestOptions


.




DEFAULT




);



}





/**







* POST /kibana_sample_data_logs/_search







* {








*     “query”: {








*        “bool”: {








*           “must”:[







*                 {“match”: { “message”: “firefox”} }







*           ],







*           “should”:[







*                {“term”: { “geo. src”: “CN”}},







*                {“term”: { “geo. dest”: “CN”}}







*           ]







*        }







*     }







* }







*/







public


ResponseBean


boolSearch


(


String


indexName) {




SearchRequest searchRequest


=


new


SearchRequest();



searchRequest


.indices(indexName);



SearchSourceBuilder searchSourceBuilder


=


new


SearchSourceBuilder();



BoolQueryBuilder boolQueryBuilder


=


QueryBuilders


.




boolQuery




();



boolQueryBuilder


.must(


QueryBuilders


.




matchQuery




(


“message”


,


“firefox”


))



.should(


QueryBuilders


.




termQuery




(


“geo.src”


,


“CN”


))



.should(


QueryBuilders


.




termQuery




(


“geo.dest”


,


“CN”


));



searchSourceBuilder


.query(


boolQueryBuilder


);



searchRequest


.source(


searchSourceBuilder


);



return


sendSearchRequest


.send(


searchRequest


,


RequestOptions


.




DEFAULT




);



}



}




2.3、文档操作类代码实现




@Service



public class


OperateDoc


{




@Resource



private


RestHighLevelClient


restHighLevelClient


;





/**







* 创建文档







*/







public


ResponseBean


insertDoc


(


User


user,


String


indexName,


String


docId) {




IndexRequest indexRequest


=


new


IndexRequest(indexName);



String userJson


=


JSONObject


.




toJSONString




(user);



if


(!docId.equals(


“noid”


)){




indexRequest


.id(docId);



}



indexRequest


.source(


userJson


,


XContentType


.




JSON




);



try


{




IndexResponse indexResponse


=


restHighLevelClient


.index(


indexRequest


,


RequestOptions


.




DEFAULT




);



if


(


indexResponse


!=


null


){




String id


=


indexResponse


.getId();



String index


=


indexResponse


.getIndex();



if


(


indexResponse


.getResult() ==


DocWriteResponse


.


Result


.




CREATED




){




System


.




out




.println(


“新增文档成功”


);



return  new


ResponseBean(


200


,


“索引文档成功”


,


id


);



}


else if


(


indexResponse


.getResult() ==


DocWriteResponse


.


Result


.




UPDATED




){




System


.




out




.println(


“覆盖文档成功”


);



return  new


ResponseBean(


200


,


“覆盖文档成功”


,


null


);



}



}



}


catch


(


IOException


e) {




e.printStackTrace();



}



return null


;



}





/**







* 查询文档







*/







public


ResponseBean


getDoc


(


String


indexName,


String


docId) {




return new


ResponseBean(


200


,


“参考TestEsHighSdk”


,indexName+docId);



}





/**







* 更新文档







*/







public


ResponseBean


updateDoc


(


String


indexName,


String


docId,


String


fieldName,


String


fieldValue) {




try


{




XContentBuilder xContentBuilder


=


XContentFactory


.




jsonBuilder




();



xContentBuilder


.startObject();



{




xContentBuilder


.field(fieldName,fieldValue);





//xContentBuilder.timeField()







}



xContentBuilder


.endObject();



UpdateRequest request


=


new


UpdateRequest(indexName, docId).doc(


xContentBuilder


);



request


.docAsUpsert(


true


);



request


.fetchSource(


true


);




/*在应答里包含当前文档的内容*/







UpdateResponse updateResponse


=


restHighLevelClient


.update(


request


,


RequestOptions


.




DEFAULT




);



GetResult getResult


=


updateResponse


.getGetResult();



if


(


getResult


.isExists()){




String sourceAsString


=


getResult


.sourceAsString();



return new


ResponseBean(


200


,


“更新文档成功”


,


sourceAsString


);



}


else


{




return new


ResponseBean(


200


,


“更新文档失败”


,indexName+


“/”


+docId+


“/”


+fieldName);



}



}


catch


(


IOException


e) {




e.printStackTrace();



}



return null


;



}





/**







* 删除文档







*/







public


ResponseBean


deleteDoc


(


String


indexName,


String


docId) {




DeleteRequest deleteRequest


=


new


DeleteRequest(indexName, docId);



try


{




DeleteResponse deleteResponse


=


restHighLevelClient


.delete(


deleteRequest


,


RequestOptions


.




DEFAULT




);



if


(


deleteResponse


.getResult() ==


DocWriteResponse


.


Result


.




NOT_FOUND




){




return new


ResponseBean(


200


,


“删除不存在的文档”


,indexName+


“/”


+docId);



}


else


{




return new


ResponseBean(


200


,


“删除文档成功”


,indexName+


“/”


+docId);



}



}


catch


(


IOException


e) {




e.printStackTrace();



}



return null


;



}



}




2.4、索引管理代码实现




@Service



public class


OperateIndex


{




@Resource



private


RestHighLevelClient


restHighLevelClient


;





/**







* 新建索引







*/







public boolean


createIndex


(


String


indexName)


throws


IOException


{




XContentBuilder xContentBuilder


=


XContentFactory


.




jsonBuilder




()



.startObject().field(


“properties”


).startObject().field(


“firstName”


)



.startObject().field(


“type”


,


“keyword”


).endObject().field(


“secondName”


)



.startObject().field(


“type”


,


“keyword”


).endObject().field(


“age”


)



.startObject().field(


“type”


,


“integer”


).endObject().field(


“content”


)



.startObject().field(


“type”


,


“text”


).endObject()



.endObject().endObject();



CreateIndexRequest createIndexRequest


=


new


CreateIndexRequest(indexName);



createIndexRequest


.mapping(


xContentBuilder


);



CreateIndexResponse createIndexResponse



=


restHighLevelClient


.indices().create(


createIndexRequest


,


RequestOptions


.




DEFAULT




);



boolean


acknowledeg


=


createIndexResponse


.isAcknowledged();



return


acknowledeg


;



}





/**







* 查询是否存在







*/







public boolean


isIndexExists


(


String


indexName) {




GetIndexRequest getIndexRequest


=


new


GetIndexRequest(indexName);



getIndexRequest


.humanReadable(


true


);



boolean


exists =


false


;



try


{




exists =


restHighLevelClient


.indices().exists(


getIndexRequest


,


RequestOptions


.




DEFAULT




);



}


catch


(


IOException


e) {




e.printStackTrace();



}



return


exists;



}





/**







* 删除索引







*/







public boolean


deleteIndex


(


String


indexName) {




DeleteIndexRequest deleteIndexRequest


=


new


DeleteIndexRequest(indexName);



deleteIndexRequest


.indicesOptions(


IndicesOptions


.




LENIENT_EXPAND_OPEN




);



boolean


acknowledged =


false


;



try


{




AcknowledgedResponse delete


=



restHighLevelClient


.indices().delete(


deleteIndexRequest


,


RequestOptions


.




DEFAULT




);



acknowledged =


delete


.isAcknowledged();



}


catch


(


IOException


e) {




e.printStackTrace();



}



return


acknowledged;



}



}




2.5、聚集索引




@Service



public class


AggsSearch


{




@Resource



private


RestHighLevelClient


restHighLevelClient


;



@Resource



private


SendSearchRequest


sendSearchRequest


;





/**







* POST /kibana_sample_data_flights/_search?filter_path=aggregations







* {








*     “query”: {








*        “term”: {“OriginCountry”: “CN”}







*        },







*     “aggs”:







*    {








*        “date_price_histogram”: {








*           “date_histogram”: {








*              “field”: “timestamp”,







*              “interval”: “month”







*            },







*           “aggs”: {








*              “avg_price”: {“avg”: {“field”: “FlightDelayMin”}}







*            }







*        }







*    }







* }







*/







public


ResponseBean


aggsExampleSearch


(


String


indexName) {




SearchRequest searchRequest


=


new


SearchRequest();



searchRequest


.indices(indexName);





/*query部分*/







SearchSourceBuilder searchSourceBuilder


=


new


SearchSourceBuilder();



searchSourceBuilder


.query(


QueryBuilders


.




termQuery




(


“OriginCountry”


,


“CN”


));





/*聚集部分*/







DateHistogramAggregationBuilder date_price_histogram


=


AggregationBuilders


.




dateHistogram




(


“date_price_histogram”


);



date_price_histogram


.field(


“timestamp”


).fixedInterval(


DateHistogramInterval


.




days




(


30


));



date_price_histogram


.subAggregation(


AggregationBuilders


.




avg




(


“avg_price”


).field(


“FlightDelayMin”


)



);



searchSourceBuilder


.aggregation(


date_price_histogram


);



searchRequest


.source(


searchSourceBuilder


);



JSONArray jsonArray


=


new


JSONArray();



try


{




SearchResponse searchResponse


=


sendSearchRequest


.sendAndProcessHits(


searchRequest


,


RequestOptions


.




DEFAULT




,


jsonArray


);



Aggregations aggregations


=


searchResponse


.getAggregations();



for


(


Aggregation aggregation


:


aggregations


){




String aggString


=


JSON


.




toJSONString




(


aggregation


);



jsonArray


.add(


JSON


.




parseObject




(


aggString


));



List


<?


extends


Histogram


.


Bucket


>


buckets


= ((


Histogram


)


aggregation


).getBuckets();



for


(


Histogram


.


Bucket bucket


:


buckets


){




System


.




out




.println(


“————————————–”


);



System


.




out




.println(


bucket


.getKeyAsString());



System


.




out




.println(


bucket


.getDocCount());



ParsedAvg parsedAvg


= (


ParsedAvg


)


bucket


.getAggregations().getAsMap().get(


“avg_price”


);



System


.




out




.println(


parsedAvg


.getValueAsString());



}



}



return new


ResponseBean(


200


,


“查询文档成功”


,


jsonArray


);



}


catch


(


IOException


e) {




e.printStackTrace();



return new


ResponseBean(


200


,


“查询文档失败”


,


null


);



}



}



}




2.6、发送请求代码实现




@Service



public class


SendSearchRequest


{




@Resource



private RestHighLevelClient restHighLevelClient;





/**







* 一般来说,非聚集的检索只需处理hits部分,直接将结果返回给前端







*/







public


ResponseBean


send


(


SearchRequest


searchRequest,


RequestOptions


options){




JSONArray jsonArray


=


new


JSONArray();



try


{




sendAndProcessHits(searchRequest,options,


jsonArray


);



return new


ResponseBean(


200


,


“查询文档”


,


jsonArray


);



}


catch


(


IOException


e) {




e.printStackTrace();



return new


ResponseBean(


200


,


“查询文档失败”


,


null


);



}



}





/**







* 处理返回结果中的hits部分







*/







public


SearchResponse


sendAndProcessHits


(


SearchRequest


searchRequest,



RequestOptions


options,


JSONArray


jsonArray)


throws


IOException


{




SearchResponse search


=


restHighLevelClient


.search(searchRequest, options);



SearchHits hits


=


search


.getHits();



for


(


SearchHit hit


:


hits


){




String src


=


hit


.getSourceAsString();



JSONObject jsonObject


=


JSON


.




parseObject




(


src


);



jsonArray.add(


jsonObject


);



}



return


search


;



}



}

代码参考地址:https://gitee.com/hankin_chj/es-platform.git