本案例使用springboot2.1.0,和ES6.5.0整合虏辫。
-
項目結(jié)構(gòu)和maven配置如下:
111.png
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
</dependencies>
- 根據(jù)ES配置以及內(nèi)部索引結(jié)構(gòu)建立相應(yīng)實體類诗茎、dao和配置:
1、實體類(注:一定要有Id屬性利花,不然綁定相應(yīng)repository持久化接口會拋異常) - 文檔類Coder
@Document(indexName = "persons", type = "coder")
public class Coder implements Serializable {
private Long id;
private String name;
private Integer age;
private Map<String,Friend> friends = new HashMap<>();
private List<String> address= new ArrayList<>();
private SubCoder subCoder = new SubCoder();
public Map<String, Friend> getFriends() {
return friends;
}
public void setFriends(Map<String, Friend> friends) {
this.friends = friends;
}
public List<String> getAddress() {
return address;
}
public void setAddress(List<String> address) {
this.address = address;
}
public SubCoder getSubCoder() {
return subCoder;
}
public void setSubCoder(SubCoder subCoder) {
this.subCoder = subCoder;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
- SubCoder 類
public class SubCoder implements Serializable {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
2微酬、application.yml配置
說明:一、yaml語法冒號后面一定要加空格
二橄务、節(jié)點客戶端(Node client)
節(jié)點客戶端作為一個非數(shù)據(jù)節(jié)點加入到本地集群中幔托。換句話說,它本身不保存任何數(shù)據(jù)蜂挪,但是它知道數(shù)據(jù)在集群中的哪個節(jié)點中柑司,并且可以把請求轉(zhuǎn)發(fā)到正確的節(jié)點迫肖。
三、傳輸客戶端(Transport client)
輕量級的傳輸客戶端可以將請求發(fā)送到遠(yuǎn)程集群攒驰。它本身不加入集群蟆湖,但是它可以將請求轉(zhuǎn)發(fā)到集群中的一個節(jié)點上。
所以兩個 Java 客戶端都是通過 9300 端口并使用 Elasticsearch 的原生 傳輸 協(xié)議和集群交互玻粪。集群中的節(jié)點通過端口 9300 彼此通信隅津。如果這個端口沒有打開,節(jié)點將無法形成一個集群劲室。Restful api交互使用9200端口
spring:
data:
elasticsearch:
cluster-name: eden-cluster01
cluster-nodes: //相應(yīng)的訪問路徑,如:0.0.0.0:9300,0.0.0.1:9500
3伦仍、Repository持久化接口配置,無需加@repository注解,因為需要實例化相應(yīng)對象時會很洋,通過反射接口實例化一個代理對象充蓝。
public interface CoderEsRepository extends ElasticsearchRepository<Coder, Long> {
/**
* 相當(dāng)于ES查詢語句
* <code>
*
* { "bool" :
* { "must" : [
* { "field" : {"name" : "?"} },
* { "field" : {"age" : "?"} }
* ]
* }
* }
* </code>
* @param name
* @param age
* @return
*/
List<Coder> findByNameAndAge(String name, Integer age);
/**
* 相當(dāng)于ES查詢語句
* <code>
*
*
* {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"age" : "?"}} ]}}
*
* </code>
* @param name
* @param age
* @return
*/
List<Coder> findByNameOrAge(String name, Integer age);
/**
* {"bool" : {"must" : {"field" : {"name" : "?"}}}}
* @param name
* @return
*/
List<Coder> findByName(String name);
/**
* {"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
* @param name
* @return
*/
List<Coder> findByNameNot(String name);
/**
* {"bool" : {"must" : {"range" : {"age" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
* @param fromAge
* @param toAge
* @return
*/
List<Coder> findByAgeBetween(Integer fromAge,Integer toAge);
/**
*
* {"bool" : {"must" : {"range" : {"age" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
* @param age
* @return
*/
List<Coder> findByAgeLessThanEqual(Integer age);
/**
* {"sort" : [{ "age" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"name" : ?}}}}
* @param name
* @return
*/
List<Coder> findByNameIsLikeOrderByAgeDesc(String name);
/**
* Query 注解查詢方式
* @param name
* @param pageable
* @return
*/
@Query("{\"bool\" : {\"must\" : {\"term\" : {\"name\" : \"?0\"}}}}")
Page<Coder> findByName(String name, Pageable pageable);
}
4、編寫相應(yīng)的查詢操作
@RestController
@RequestMapping("/persons/coder")
public class CoderController {
@Autowired
CoderEsRepository coderEsRepository;
/**
*
* @return
*/
@GetMapping
public ResponseEntity get() {
//單個屬性查詢
// List<Coder> coderByName= coderEsRepository.findByName("lf666'");
//單個屬性分頁查詢
// Page<Coder> coderByPaging = coderEsRepository.findByName("lf666", PageRequest.of(0, 10));
List<Coder> byAgeDesc = coderEsRepository.findByNameIsLikeOrderByAgeDesc("l");
//屬性是對象時查詢
SubCoder subCoder = new SubCoder();
subCoder.setAge(20);
subCoder.setName("subEden");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("subCoder.name", subCoder.getName()))
.must(QueryBuilders.matchQuery("subCoder.age",subCoder.getAge()));
Iterable<Coder> search = coderEsRepository.search(boolQueryBuilder);
//屬性集合中是否包含指定值查詢
BoolQueryBuilder zsan = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("address", "bj"));
Iterable<Coder> search1 = coderEsRepository.search(zsan);
//復(fù)雜查詢自定義排序規(guī)則
BoolQueryBuilder builder = QueryBuilders.boolQuery().must(QueryBuilders.rangeQuery("age").from(10).to(200));
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withFilter(builder)
.withSort(SortBuilders.fieldSort("age").order(SortOrder.ASC));
Iterable<Coder> coders = coderEsRepository.search(nativeSearchQueryBuilder.build());
return new ResponseEntity(coders, HttpStatus.OK);
}