Elasticsearch原生的api,TransportClient可以支持2.x,5.x版本,TransportClient 将会在Elasticsearch 7.0弃用并在8.0中完成删除。
是Java社区开发的,是Elasticsearch的Java Http Rest客户端。
与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查询、聚集查询等)就显得力不从心了,此时,我们还是只能使用原生查询。
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
具体代码在模块es-low-level模块下
<dependencies>
<dependency>
<groupId>org.elasticsearch.clientgroupId>
<artifactId>elasticsearch-rest-clientartifactId>
<version>7.7.0version>
dependency>
dependencies>
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);
Response response = restClient.performRequest(request);
System.out.println(response);
System.out.println(EntityUtils.toByteArray(response.getEntity()));
因为Java Low Level REST Client用法比较原始,在实际工作中用的比较少所以大概了解下用法即可,对应的类是TestEsLowSdk。
具体代码在模块es-high-level模块下
<dependency>
<groupId>org.elasticsearch.clientgroupId>
<artifactId>elasticsearch-rest-high-level-clientartifactId>
<version>7.7.0version>
dependency>
代码对应的类是 TestEsHighSdk
RestClientBuilder restClientBuilder = RestClient.builder( new HttpHost("192.168.0.101",9200,"http"));
/*创建索引*/
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
/* 这里可以对索引对象进行属性设置 */
createIndexRequest.settings(Settings.builder()
.put("index.number_of_shards",3)
.put("index.codec","best_compression"));
Map
message.put("type","text");
Map
properties.put("message",message);
Map
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
message.put("type", "text");
Map
properties.put("message", message);
Map
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返回给我们。
基本上和创建索引的思路是一样的
/*索引(保存)文档*/
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返回给我们。
使用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-highlevel模块下:
<dependency>
<groupId>org.elasticsearchgroupId>
dependency>
<dependency>
<groupId>org.elasticsearch.clientgroupId>
dependency>
为方便我们的使用,我们还会引入一些其他的组件,比如fastjson和Swagger2:
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.69version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>2.9.2version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>2.9.2version>
dependency>
比较关键的类是:
SendSearchRequest:通用的发送Search请求,并处理响应结果的服务。其中主要包括了索引的管理、文档的管理、_search接口基本用法、基于词项的查询、基于全文的查询、基于全文的模糊查询、组合查询、聚集查询的相关范例,详情参阅相关代码。
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);
}
}
/**
* 给前端页面返回的应答实体
*/
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;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@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);
}
}
@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);
}
}
@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;
}
}
@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;
}
}
@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));
Listextends 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);
}
}
}
@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