ElasticSearch系列(四)–springboot使用ElasticsearchRestTemplate整合ElasticSearch,实现文本高亮检索

  • Post author:
  • Post category:其他




前言

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访问:

在这里插入图片描述



版权声明:本文为zisuu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。