1 java操作ES方式
1.1 操作ES 9300端口(TCP) 但开发中不在9300进行操作
ES集群节点通信使用的也是9300端口
如果通过9300操作ES,需要与ES建立长连接 可通过引入spring-data-elasticsearch:transport-api.jar
不在9300操作原因:
1.springboot版本不同,transport-api.jar不同,不能适配ES版本
2.官方在7.x版本已经不建议在9300操作ES,8以后会废弃ES通过9300操作的jar包
1.2 操作ES 9200端口(HTTP) 优选Elasticsearch-Rest-Client
通过9200对ES发送Http请求就可以了
1.使用第三方JestClient操作ES:更新慢
2.RestTemplate、HttpClient、OkHttp:发送HTTP请求,但如果操作ES一些DSL语句,需要自己封装,麻烦
3.Elasticsearch-Rest-Client(elasticsearch-rest-high-level-client):官方RestClient,封装了ES操作,API层次分明,上手简单
2 整合
2.1引入elasticsearch-rest-high-level-client依赖
xml
<!--elasticsearch-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>
刷新Maven 会发现elasticsearch和elasticsearch-rest-client版本是7.17.4,并不是7.4.2
原因是因为springboot对ES版本做了管理,当前springboot默认整合spring-data-elasticsearch操作ES
修改版本问题
如果使用Maven进行一个直接或间接继承spring-boot-dependencies(比如spring-boot-starter-parent)的构建,并想覆盖一个特定的
第三方依赖版本,可以添加<properties>标签,并重写第三方依赖版本
xml
<properties>
<elasticsearch.version>7.4.2</elasticsearch.version>
</properties>
如果使用<scope>import</scope>,将spring-boot-dependencies添加到自己的dependencyManagement片段,
那么必须重新定义artifact而不是重写第三方依赖版本
xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.4.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.4.2</version>
</dependency>
</dependencies>
</dependencyManagement>
2.2 添加ES配置
java
@Configuration
public class ElasticsearchConfig {
/**
* 配置请求选项
* 参考:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/java-rest-low-usage-requests.html#java-rest-low-usage-request-options
*/
public static final RequestOptions COMMON_OPTIONS;
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// builder.addHeader("Authorization", "Bearer " + TOKEN);
// builder.setHttpAsyncResponseConsumerFactory(
// new HttpAsyncResponseConsumerFactory
// .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}
@Bean
public RestHighLevelClient esRestClient() {
// RestHighLevelClient highLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.179.101", 9200, "Http"),
// new HttpHost("192.168.179.101", 9201, "Http")));
RestHighLevelClient highLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.179.101", 9200, "Http")));
return highLevelClient;
}
}
2.3 测试及验证整合结果
java
@SpringBootTest
public class SearchApplicationTests {
@Autowired
private RestHighLevelClient client;
@Data
@ToString
static class Account {
private int account_number;
private int balance;
private String firstname;
private String lastname;
private int age;
private String gender;
private String address;
private String employer;
private String email;
private String city;
private String state;
}
/**
* 在new_bank中搜索address中包含mill的所有人的年龄分布以及平均薪资
*/
@Test
public void searchData() throws IOException {
//1,创建检索请求
SearchRequest searchRequest = new SearchRequest();
//1.1,指定检索索引
searchRequest.indices("new_bank");
//1.2,构造检索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("address", "Mill"));
//1.2.1,按照年龄分布进行聚合
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
searchSourceBuilder.aggregation(ageAgg);
//1.2.2,计算平均薪资
AvgAggregationBuilder avgBalance = AggregationBuilders.avg("avgBalance").field("balance");
searchSourceBuilder.aggregation(avgBalance);
System.out.println("检索条件" + searchSourceBuilder);
searchRequest.source(searchSourceBuilder);
//2,执行同步检索
SearchResponse searchResponse = client.search(searchRequest, ElasticsearchConfig.COMMON_OPTIONS);
System.out.println("执行检索结果" + searchResponse);
//3,提取命中结果hits
SearchHits hits = searchResponse.getHits();
SearchHit[] hitsHits = hits.getHits();
for (SearchHit hitsHit : hitsHits) {
String sourceAsString = hitsHit.getSourceAsString();
Account account = JSONObject.parseObject(sourceAsString, Account.class);
System.out.println(account);
}
//4,提取聚合信息
Aggregations aggregations = searchResponse.getAggregations();
Terms ageAggRes = aggregations.get("ageAgg");
List<? extends Terms.Bucket> aggResBuckets = ageAggRes.getBuckets();
for (Terms.Bucket aggResBucket : aggResBuckets) {
System.out.println("年龄:" + aggResBucket.getKeyAsString() + "总和:" + aggResBucket.getDocCount());
}
Avg balance = aggregations.get("avgBalance");
System.out.println(balance.getValue());
}
/**
* https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/java-rest-high-document-index.html
*/
@Test
public void testEsAdd() throws IOException {
//指定索引
IndexRequest indexRequest = new IndexRequest("users");
//指定id
indexRequest.id("1");
//封装数据
User user = new User();
user.setUserName("张三");
user.setAge(27);
user.setGender("M");
String jsonString = JSONObject.toJSONString(user);
//指定数据类型为JSON
indexRequest.source(jsonString, XContentType.JSON);
//执行同步操作
IndexResponse index = client.index(indexRequest, ElasticsearchConfig.COMMON_OPTIONS);
System.out.println(index);
}
@Data
class User {
private String userName;
private String gender;
private Integer age;
}
}
xml
kibana
GET /users/_search
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "users",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"age" : 27,
"gender" : "M",
"userName" : "张三"
}
}
]
}
}