springboot使用ElasticSearch
使用ES官方自帶的java客戶端(Java High Level REST Client)進行操作,不使用spring data 封裝好的模板。
因為沒有人比ES官方更了解自己的產品
- 導入依賴包
<!--Elastic Search 客戶端 start-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.2</version>
</dependency>
<!--如果elasticsearch-rest-high-level-client包中依賴的elasticsearch等版本不一致,需要手動引入相同版本-->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.6.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.6.2</version>
</dependency>
<!--Elastic Search 客戶端 end-->
- 創建application.yml 配置文件
elasticsearch:
hostList: localhost:9200 #多個節點用逗號隔開
- 添加配置類
@Component
@PropertySource("classpath:application.yml")//配置文件地址,可以自定義
@ConfigurationProperties("elasticsearch")//屬性前綴
public class ElasticSearchConfig {
// @Value("${elasticsearch.hostList}")
private String hostList;//配置文件中的屬性
public String getHostList() {
return hostList;
}
public void setHostList(String hostList) {
this.hostList = hostList;
}
@Bean(value = "RestHighLevelClient", destroyMethod = "close")
public RestHighLevelClient restHighLevelClient() {
//通過逗號分割節點
String[] split = hostList.split(",");
HttpHost[] httpHosts = new HttpHost[split.length];
for (int i = 0; i < split.length; i++) {
//通過冒號分離出每一個節點的ip,port
String[] split1 = split[i].split(":");
//這里http寫固定了,只為測試使用,可以通過讀取配置文件賦值的方式優化
httpHosts[i] = new HttpHost(split1[0], Integer.parseInt(split1[1]), "http");
}
return new RestHighLevelClient(RestClient.builder(httpHosts));
}
}
- 在springboot test中測試CURD操作,具體查看 官方文檔
@SpringBootTest
public class ElasticTest {
@Autowired
@Qualifier("RestHighLevelClient")
private RestHighLevelClient client;
/**
* 添加數據
* @throws IOException
*/
@Test
public void index() throws IOException {
UserTest userTest = new UserTest();
userTest.setName("董28");
userTest.setSex("男");
//由於客戶端不支持自定義實體對象類作為添加數據的參數,所以提前先將對象轉化為Map對象
Map map = entityToMap(userTest);
System.out.println(map);
IndexRequest indexRequest = new IndexRequest("posts")
.source(map);
//異步
client.indexAsync(indexRequest, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() {
@Override
public void onResponse(IndexResponse indexResponse) {
System.out.println(indexResponse);
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
//新建
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
//修改
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
//
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();
}
}
}
@Override
public void onFailure(Exception e) {
System.out.println("exception...");
}
});
//同步
/*IndexRequest indexRequest = new IndexRequest("posts")
.id("3").source(map);
IndexResponse index = client.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(index);*/
}
/**
* 通過索引index,id查詢
*
*/
@Test
public void get() throws IOException {
GetRequest getRequest = new GetRequest("posts", "1");
/*FetchSourceContext fetchSourceContext = new FetchSourceContext(true, new String[]{"sex"}, Strings.EMPTY_ARRAY);
getRequest.fetchSourceContext(fetchSourceContext)*/
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
if (getResponse.isExists()) {
System.out.println(getResponse);
System.out.println(getResponse.getId());
System.out.println(getResponse.getSource());
System.out.println(getResponse.getSourceAsMap());
UserTest userTest1 = entityConvert(getResponse.getSourceAsString(), UserTest.class);
System.out.println(userTest1);
UserTest userTest2 = entityConvert(getResponse.getSource(), UserTest.class);
System.out.println(userTest2);
}
}
@Test
public void update() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("posts", "8");
updateRequest.doc("sex", "女");
UpdateResponse update = client.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(update);
}
@Test
public void delete() throws IOException {
DeleteRequest deleteRequest = new DeleteRequest("posts");
DeleteResponse delete = client.delete(deleteRequest, RequestOptions.DEFAULT);
}
/**
* 通過字段值查詢
* @throws IOException
*/
@Test
public void search() throws IOException {
SearchRequest searchRequest = new SearchRequest("posts");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//通過匹配某一字段查詢
// searchSourceBuilder.query(QueryBuilders.termQuery("name","董"));
//選出指定結果字段
searchSourceBuilder.fetchSource(new String[]{"id"},Strings.EMPTY_ARRAY);
//對結果排序
// searchSourceBuilder.sort(new FieldSortBuilder("id").order(SortOrder.DESC));
//聚集結果
searchSourceBuilder.aggregation(
AggregationBuilders
.max("maxValue")//命名
.field("id"));//指定聚集的字段
//查詢所有
// searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//從0開始
// searchSourceBuilder.from(2).size(2);
searchRequest.source(searchSourceBuilder);
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(search);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
private static class UserTest {
private int id;
private String name;
private String sex;
private Others others = new Others("132@qq.com", "199");
}
@Data
@AllArgsConstructor
private static class Others {
private String email;
private String phone;
}
/**
* 實體對象轉化為map
* @param object
* @return
* @throws JsonProcessingException
*/
static Map entityToMap(Object object) throws JsonProcessingException {
Map map = entityConvert(object, HashMap.class);
return map;
}
/**
* 一個對象轉化為另一個有相同屬性的對象
* @param object
* @param clazz
* @param <T>
* @return
* @throws JsonProcessingException
*/
static <T> T entityConvert(Object object, Class<T> clazz) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
String s;
if (object instanceof String) {
s = String.valueOf(object);
} else {
s = objectMapper.writeValueAsString(object);
}
T t = objectMapper.readValue(s, clazz);
return t;
}
}