前言
ElasticsearchRestTemplate是spring-data-elasticsearch项目中的一个类,和其他spring项目中的template类似。
网上的学习资料大都是基于ElasticsearchTemplate,但是ElasticsearchTemplate在未来的版本会被废除
预备知识
- 建立索引
因为是基于springboot,那就不再使用kibana进行建立索引,而是用springboot来创建.创建索引的api:
ElasticsearchRestTemplate.createIndex(实体类.class)
如,现在创建一个名为esBean的实体类
相当于建库:
@Document用于指定索引
@Field(type = FieldType.Text,analyzer = “ik_max_word”)用于指定类型
@Data
@NoArgsConstructor
@Document(indexName = "test")
public class esBean {
@Id
private int id;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String tags;
public esBean(int id,String name,String tags){
this.id=id;
this.name=name;
this.tags=tags;
}
}
service层:
public class esService implements IesService {
@Autowired
private ElasticsearchRestTemplate template;
@Override
public void create(){
template.createIndex(esBean.class);
}
}
像这样,就会自动建立一个名为test的索引,表结果就是esBean的成员
存储数据
需要一个持久化层的接口去继承ElasticsearchRepository,接着在service层中,依赖注入,直接调用其saveAll()方法即可,如下:
持久层:(可以在这里做一些搜索查询)
@Service
public interface esMapper extends ElasticsearchRepository<esBean,Long> {
}
service层:
可以看到,saveAll,findAll这些方法是原来就有的,无需自己定义
public class esService implements IesService {
@Autowired
private ElasticsearchRestTemplate template;
@Autowired
esMapper mapper;
@Override
public Iterator<esBean> findAll() {
return mapper.findAll().iterator();
}
public void create(){
template.createIndex(esBean.class);
}
@Override
public void saveAll(List<esBean> list) {
mapper.saveAll(list);
}
}
controller层:
@Autowired
IesService iesService;
@GetMapping("/init1")
public String init1(){
iesService.create();
// id name tags
List<esBean>list=new ArrayList<>();
list.add(new esBean(1,"张三锕爱","很帅,有很多人喜欢他"));
list.add(new esBean(2,"李四酷狗","很帅,但是讨厌他"));
list.add(new esBean(3,"王五王二爷","很丑,有是喜欢他"));
list.add(new esBean(4,"张三王二婆","很帅,有没人喜欢他"));
iesService.saveAll(list);
return "success";
}
ElasticsearchRestTemplate的基本api
SearchQuery 总的查询
BoolQueryBuilder bool查询,可在后面加上must,mustNot,should等等
MatchQueryBuilder 匹配查询
TermQueryBuilder 倒排索引查询
HighlightBuilder 高亮查询,用于设置要高亮的field
SearchHit 查询结果
实现文本高亮检索步骤
实体类:
@Data
@NoArgsConstructor
@Document(indexName = "test5")
public class esBean {
@Id
private int id;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String tags;
public esBean(int id,String name,String tags){
this.id=id;
this.name=name;
this.tags=tags;
}
}
持久层
@Service
public interface esMapper extends ElasticsearchRepository<esBean,Long> {
}
service:
public interface IesService {
public Iterator<esBean> findAll();
public void saveAll(List<esBean> list);
public void create();
public AggregatedPage testForHigh() throws IOException;
}
@Service
public class esService implements IesService {
@Autowired
private ElasticsearchRestTemplate template;
@Autowired
esMapper mapper;
@Override
public Iterator<esBean> findAll() {
return mapper.findAll().iterator();
}
public void create(){
template.createIndex(esBean.class);
}
@Override
public void saveAll(List<esBean> list) {
mapper.saveAll(list);
}
public AggregatedPage testForHigh() throws IOException {
String preTag = "<font color='#dd4b39'>";//google的色值
String postTag = "</font>";
BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder()
.must(new MatchQueryBuilder("tags","很帅"));
SearchQuery searchQuery=new NativeSearchQueryBuilder(). //总的查询
withQuery(boolQueryBuilder). //设置bool查询
withHighlightFields(new HighlightBuilder.Field("name").preTags(preTag).postTags(postTag)).//设置高亮效果
withHighlightFields(new HighlightBuilder.Field("tags").preTags(preTag).postTags(postTag)).build();
AggregatedPage<esBean> ideas=template.queryForPage(searchQuery, esBean.class, new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
List<esBean> list = new ArrayList<>();
for(SearchHit hit:searchResponse.getHits()){//获取遍历查询结果
if(searchResponse.getHits().getHits().length<=0)return null;
esBean bean=new esBean();
Map map=hit.getSourceAsMap();
System.out.println(map);
bean.setId((Integer)map.get("id"));
bean.setName((String)map.get("name"));
HighlightField name=hit.getHighlightFields().get("name");
if(name!=null){
bean.setName(name.fragments()[0].toString()); //得到高亮的结果
}
HighlightField tags=hit.getHighlightFields().get("tags");
if(tags!=null){
bean.setTags(tags.fragments()[0].toString());
}
list.add(bean);
}
if(list.size()>0)return new AggregatedPageImpl<>((List<T>)list);
return null;
}
@Override
public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
return null;
}
});
ideas.get().forEach(model->{
System.out.println(model);
});
return ideas;
}
@Override
public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
return null;
}
});
ideas.get().forEach(model->{
System.out.println(model);
});
return ideas;
}
}
controller:
@RestController
@RequestMapping("/elastic")
public class ElasticController {
@Autowired
IesService iesService;
@GetMapping("/init1")
public String init1(){
iesService.create();
// id name tags
List<esBean>list=new ArrayList<>();
list.add(new esBean(1,"张三锕爱","很帅,有很多人喜欢他"));
list.add(new esBean(2,"李四酷狗","很帅,但是讨厌他"));
list.add(new esBean(3,"王五王二爷","很丑,有是喜欢他"));
list.add(new esBean(4,"张三王二婆","很帅,有没人喜欢他"));
iesService.saveAll(list);
return "success";
}
@GetMapping("/get1")
public AggregatedPage get1() throws IOException {
return iesService.testForHigh();
}
}
postman访问: