一、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
二、配置ElasticSearch设置 的两种方法
1、在application.yml中配置
spring:
data:
elasticsearch:
cluster-nodes: localhost:9300
cluster-name: es-wyf
2、使用配置类进行配置
/**
* ElasticSearch 客户端配置
*/
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
}
三、编写一个实体类,使用 这个实体类来操作ES的CRUD
@Data
@Accessors(chain = true)
@Document(indexName = "blog", type = "java")
public class BlogModel implements Serializable {
private static final long serialVersionUID = 6320548148250372657L;
@Id
private String id;
private String title;
//@Field(type = FieldType.Date, format = DateFormat.basic_date)
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date time;
}
public interface BlogRepository extends ElasticsearchRepository<BlogModel, String> {
}
四、编写Controller类注入业务类,使用ES的CURD
@RestController
@RequestMapping("/blog")
public class BlogController {
@Autowired
private BlogRepository blogRepository;
//也可以换成ES自带的业务类
//@Autowired
//private ElasticsearchTemplate elasticsearchTemplate;
//添加ES数据
@PostMapping("/add")
public Result add(@RequestBody BlogModel blogModel) {
blogRepository.save(blogModel);
return Result.success();
//查询单条ES中的数据
@GetMapping("/get/{id}")
public Result getById(@PathVariable String id) {
if (StringUtils.isEmpty(id))
return Result.error();
Optional<BlogModel> blogModelOptional = blogRepository.findById(id);
if (blogModelOptional.isPresent()) {
BlogModel blogModel = blogModelOptional.get();
return Result.success(blogModel);
}
return Result.error();
}
//获取全部数据
@GetMapping("/get")
public Result getAll() {
Iterable<BlogModel> iterable = blogRepository.findAll();
List<BlogModel> list = new ArrayList<>();
iterable.forEach(list::add);
return Result.success(list);
}
//更新数据
@PostMapping("/update")
public Result updateById(@RequestBody BlogModel blogModel) {
String id = blogModel.getId();
if (StringUtils.isEmpty(id))
return Result.error();
blogRepository.save(blogModel);
return Result.success();
}
//删除单条数据
@DeleteMapping("/delete/{id}")
public Result deleteById(@PathVariable String id) {
if (StringUtils.isEmpty(id))
return Result.error();
blogRepository.deleteById(id);
return Result.success();
}
//删除全部数据
@DeleteMapping("/delete")
public Result deleteById() {
blogRepository.deleteAll();
return Result.success();
}
}
}
五,一些写的比较好的ES搜索实例
1、 全局搜索
/**
* 全文搜索
* @param keyword 关键字
* @param page 当前页,从0开始
* @param size 每页大小
* @return {@link Result} 接收到的数据格式为json
*/
@GetMapping("/full")
public Mono<Result> full(String keyword, int page, int size) {
// System.out.println(new Date() + " => " + keyword);
// 校验参数
if (StringUtils.isEmpty(page))
page = 0; // if page is null, page = 0
if (StringUtils.isEmpty(size))
size = 10; // if size is null, size default 10
// 构造分页类
Pageable pageable = PageRequest.of(page, size);
// 构造查询 NativeSearchQueryBuilder
NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder()
.withPageable(pageable)
;
if (!StringUtils.isEmpty(keyword)) {
// keyword must not null
searchQueryBuilder.withQuery(QueryBuilders.queryStringQuery(keyword));
}
/*
SearchQuery
这个很关键,这是搜索条件的入口,
elasticsearchTemplate 会 使用它 进行搜索
*/
SearchQuery searchQuery = searchQueryBuilder.build();
// page search
Page<PhoneModel> phoneModelPage = elasticsearchTemplate.queryForPage(searchQuery, PhoneModel.class);
// return
return Mono.just(Result.success(phoneModelPage));
}
2.
/**
* 高级搜索,根据字段进行搜索
* @param name 名称
* @param color 颜色
* @param sellingPoint 卖点
* @param price 价格
* @param start 开始时间(格式:yyyy-MM-dd HH:mm:ss)
* @param end 结束时间(格式:yyyy-MM-dd HH:mm:ss)
* @param page 当前页,从0开始
* @param size 每页大小
* @return {@link Result}
*/
@GetMapping("/_search")
public Mono<Result> search(String name, String color, String sellingPoint, String price, String start, String end, int page, int size) {
// 校验参数
if (StringUtils.isEmpty(page) || page < 0)
page = 0; // if page is null, page = 0
if (StringUtils.isEmpty(size) || size < 0)
size = 10; // if size is null, size default 10
// 构造分页对象
Pageable pageable = PageRequest.of(page, size);
// BoolQueryBuilder (Elasticsearch Query)
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
if (!StringUtils.isEmpty(name)) {
boolQueryBuilder.must(QueryBuilders.matchQuery("name", name));
}
if (!StringUtils.isEmpty(color)) {
boolQueryBuilder.must(QueryBuilders.matchQuery("colors", color));
}
if (!StringUtils.isEmpty(color)) {
boolQueryBuilder.must(QueryBuilders.matchQuery("sellingPoints", sellingPoint));
}
if (!StringUtils.isEmpty(price)) {
boolQueryBuilder.must(QueryBuilders.matchQuery("price", price));
}
if (!StringUtils.isEmpty(start)) {
Date startTime = null;
try {
startTime = DateTimeUtil.stringToDate(start, DateTimeFormat.yyyy_MM_dd_HH_mm_ss);
} catch (ParseException e) {
e.printStackTrace();
}
boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").gt(startTime.getTime()));
}
if (!StringUtils.isEmpty(end)) {
Date endTime = null;
try {
endTime = DateTimeUtil.stringToDate(end, DateTimeFormat.yyyy_MM_dd_HH_mm_ss);
} catch (ParseException e) {
e.printStackTrace();
}
boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime").lt(endTime.getTime()));
}
// BoolQueryBuilder (Spring Query)
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withPageable(pageable)
.withQuery(boolQueryBuilder)
.build()
;
// page search
Page<PhoneModel> phoneModelPage = elasticsearchTemplate.queryForPage(searchQuery, PhoneModel.class);
// return
return Mono.just(Result.success(phoneModelPage));
}