1)、9300,TCP
spring-data-elasticsearch:transport-apl.jar;
spfingboot版本不同,transport-api.jar不同,不能适配es版本
7.x已经不建议使用,8以后就要废弃
2)、9200.HTTP
JestClient:非官方,更新慢
Resttemplate: 模拟发HTTP请求,ES很多操作需要自己封装,麻烦
Httpclent:同上
ElasticSearch-Rest-Client:官方RestClient,封装了ES操作,API层次分明,上手简单
最终选择 ElasticSearch-Rest-Clent(elasticSearch-rest-high-level-client)
官方文档
开始整合
1)、创建SpringBoot ES 搜索服务 导入依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>
ElasticSearch-Rest-Client Java High Level REST Client的版本必须小于等于你的elasticsearch版本,建议版本一致
springboot有管理es版本,所以得手动改成当前es版本
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.4.2</elasticsearch.version>
</properties>
可见 nacos得注册与发现
3)、编写配置,将客户端注入spring容器
/**
* @program: MyMall
* @description: ES配置类
* @author: DAIHAO
* @created: 2020/05/09 22:53
*/
@Configuration
public class EsConfig {
@Bean
public RestHighLevelClient esRestClient() {
RestClientBuilder builder = null;
HttpHost host = new HttpHost("192.168.175.130",9200,"http");
builder = RestClient.builder(host);
RestHighLevelClient client = new RestHighLevelClient(builder);
return client;
}
}
4)、测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class MallSearchApplicationTests {
@Autowired
RestHighLevelClient client;
@Test
public void contextLoads() {
System.out.println(client);
//org.elasticsearch.client.RestHighLevelClient@f438904
}
}
5)、使用单实例RestHighLevelClient
RestHighLevelClient中的所有API都接受一个RequestOptions,您可以使用它们以不会改变Elasticsearch执行请求的方式自定义请求。例如,在这里您可以指定NodeSelector来控制哪个节点接收请求
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();
}
/**
* 测试存储数据到es
*/
@Test
public void index() throws IOException {
//指定索引
IndexRequest indexRequest = new IndexRequest("users");
//指定ID 如果不设置自动生成
indexRequest.id("1");
//1、使用kv结构
//index.source("userName","daihao","age","18");
//2、使用json
User user = new User();
user.setName("DAIHAO");
user.setAge(18);
user.setGender("男");
String json = JSON.toJSONString(user);
indexRequest.source(json, XContentType.JSON);
//执行同步存储 RequestOptions.DEFAULT:请求设置项
IndexResponse index = client.index(indexRequest, RequestOptions.DEFAULT);
//提取有用得响应数据
System.out.println(index);
//IndexResponse[index=users,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
//java.lang.IllegalArgumentException: The number of object passed must be even but was [1]
//错误 没有设置传递的内容格式 XContentType.JSON
}
@Data
class User {
private String name;
private String gender;
private Integer age;
}
/**
* 复杂查询
*/
@Test
public void searchData() throws IOException {
//创建检索请求
SearchRequest searchRequest = new SearchRequest();
//指定索引
searchRequest.indices("bank");
//指定DSL,检索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchQuery("address", "mill"));
//按照年龄的值分布聚合
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg")
.field("age").size(10);
sourceBuilder.aggregation(ageAgg);
//计算平均薪资
AvgAggregationBuilder balanceVag = AggregationBuilders.avg("balanceVag")
.field("balance");
sourceBuilder.aggregation(balanceVag);
//System.out.println(sourceBuilder.toString());
searchRequest.source(sourceBuilder);
//执行
SearchResponse searchResponse = client.search(searchRequest, EsConfig.COMMON_OPTIONS);
//获取命中数据
SearchHits searchHits = searchResponse.getHits();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit : hits) {
String str = hit.getSourceAsString();
Account account = JSON.parseObject(str, Account.class);
System.out.println("account:" + account);
//account_number=970, balance=19648, firstname=Forbes, lastname=Wallace, age=28, gender=M,
//address=990 Mill Road, employer=Pheast, [email protected], city=Lopezo, state=AK)
}
//获取这次检索的到的分析信息
Aggregations aggregations = searchResponse.getAggregations();
for (Aggregation aggregation : aggregations.asList()) {
System.out.println("当前聚合:" + aggregation.getName());
//当前聚合:ageAgg
//当前聚合:balanceVag
}
Terms ageAgg1 = aggregations.get("ageAgg");
for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
String str = bucket.getKeyAsString();
System.out.println("年龄:" + str + "===>" + bucket.getDocCount());
// 年龄:38===>2
// 年龄:28===>1
// 年龄:32===>1
}
Avg balanceVag1 = aggregations.get("balanceVag");
System.out.println("平均薪资:" + balanceVag1.getValueAsString());
//平均薪资:25208.0
}
@ToString
@Data
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;
}
1、 提供按关键字查询的全文搜索功能。
2、 著名的ELK框架(ElasticSearch,Logstash,Kibana),实现企业海量日志的处理分析的解决方案。大数据领域的重要一份子