前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >springboot 2.2.x +ES 7.4.x 实现分词和高亮搜索

springboot 2.2.x +ES 7.4.x 实现分词和高亮搜索

作者头像
smallmayi
发布2022-05-12 11:25:51
7640
发布2022-05-12 11:25:51
举报
文章被收录于专栏:small专栏small专栏

使用springboot2.2.1,elasticsearch7.4.2

1. pom
代码语言:javascript
复制
<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

其他依赖,web,lombok

代码语言:javascript
复制
<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
2.application.properties

application.properties es默认没有密码,暂时未设定用户密码

代码语言:javascript
复制
#elasticsearh
spring.elasticsearch.rest.uris=http://192.168.4.100:9200
3.实体类
代码语言:javascript
复制
@Data
@NoArgsConstructor
//需要使用Document注解,indexName:库的名称,type:存储类型,一般使用bean的名称,
//分片(Shard)以及副本(Replica),分布式存储系统为了解决单机容量以及容灾的问题,都需要有分片以及副本机制。
@Document(indexName = "ems", type = "_doc", shards = 1, replicas = 0)
public class DocBean {

    @Id
    private Long id;

    @Field(type = FieldType.Keyword)
    private String firstCode;

    @Field(type = FieldType.Keyword)
    private String secordCode;

    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String content;

    @Field(type = FieldType.Integer)
    private Integer type;

    public DocBean(Long id, String firstCode, String secordCode, String content, Integer type) {
        this.id = id;
        this.firstCode = firstCode;
        this.secordCode = secordCode;
        this.content = content;
        this.type = type;
    }
}
4.dao
代码语言:javascript
复制
public interface ElasticRepository extends ElasticsearchRepository<DocBean, Long> {

    //默认的注释
    //@Query("{\"bool\" : {\"must\" : {\"field\" : {\"content\" : \"?\"}}}}")
    Page<DocBean> findByContent(String content, Pageable pageable);

    Page<DocBean> findByFirstCode(String firstCode, Pageable pageable);

    Page<DocBean> findBySecondCode(String SecondCode, Pageable pageable);

}
5.service
代码语言:javascript
复制
public interface ElasticService {

    void createIndex();

    void deleteIndex(String index);

    void save(DocBean docBean);

    void saveAll(List<DocBean> list);

    Iterator<DocBean> findAll();

    Page<DocBean> findByContent(String content);

    Page<DocBean> findByFirstCode(String firstCode);

    Page<DocBean> findBySecondCode(String SecondCode);

    Page<DocBean> query(String key);
}
代码语言:javascript
复制
@Service("elasticService")
public class ElasticServiceImpl implements ElasticService {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;
    @Autowired
    private ElasticRepository elasticRepository;

    private Pageable pageable = PageRequest.of(0, 10);

    @Override
    public void createIndex() {
        elasticsearchTemplate.createIndex(DocBean.class);
        //创建mapping,使分词生效
        elasticsearchTemplate.putMapping(DocBean.class);
    }

    @Override
    public void deleteIndex(String index) {
        elasticsearchTemplate.deleteIndex(index);
    }

    @Override
    public void save(DocBean docBean) {
        elasticRepository.save(docBean);
    }

    @Override
    public void saveAll(List<DocBean> list) {
        elasticRepository.saveAll(list);
    }

    @Override
    public Iterator<DocBean> findAll() {
        return elasticRepository.findAll().iterator();
    }

    @Override
    public Page<DocBean> findByContent(String content) {
        return elasticRepository.findByContent(content, pageable);
    }

    @Override
    public Page<DocBean> findByFirstCode(String firstCode) {
        return elasticRepository.findByFirstCode(firstCode, pageable);
    }

    @Override
    public Page<DocBean> findBySecondCode(String SecondCode) {
        return elasticRepository.findBySecondCode(SecondCode, pageable);
    }

    @Override
    public Page<DocBean> query(String key) {
        return elasticRepository.findByContent(key, pageable);
    }
}
6.ctrl
代码语言:javascript
复制
@RestController
@RequestMapping("/elastic")
public class ElasticController {

    @Autowired
    private ElasticService elasticService;

    @GetMapping("/init")
    public void init() {
        elasticService.createIndex();
        List<DocBean> list = new ArrayList<>();
        list.add(new DocBean(1L, "XX0193", "XX8064", "中国", 1));
        list.add(new DocBean(2L, "XX0210", "XX7475", "我是一个中国人", 1));
        list.add(new DocBean(3L, "XX0257", "XX8097", "我爱中华人民共和国", 1));
        elasticService.saveAll(list);

    }

    @GetMapping("/all")
    public Iterator<DocBean> all() {
        return elasticService.findAll();
    }

    @GetMapping("/findByContent")
    public Page<DocBean> findByContent(String content) {
        Page<DocBean> x = elasticService.findByContent(content);
        return x;
    }


    @GetMapping("/findByFirstCode")
    public Page<DocBean> findByFirstCode() {
        return elasticService.findByFirstCode("XX0193");
    }

    @GetMapping("/findBySecondCode")
    public Page<DocBean> findBySecondCode() {
        return elasticService.findBySecondCode("XX7475");
    }
}
7.测试

init方法初始化数据:http://localhost:8080/elastic/init 测试

在这里插入图片描述
在这里插入图片描述
8.高亮显示

上面已经实现了分词,因为ElasticsearchRepository提供的实现接口是封装好的,那我们就把接口的实现单独抽出来。 在实现类重写了ElasticsearchRepository提供的findByContent方法,添加前缀后缀

代码语言:javascript
复制
@Override
    public Page<DocBean> findByContent(String content) {

        // 定义高亮字段
        HighlightBuilder.Field contentField = new HighlightBuilder.Field("content").preTags("<span>").postTags("</span>");
        // 构建查询内容
        QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder(content);
        // 查询匹配的字段
        queryBuilder.field("content");

        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder)
                .withHighlightFields(contentField).build();
        long count = elasticsearchTemplate.count(searchQuery, DocBean.class);
        System.out.println("系统查询个数:--》" + count);
        if (count == 0) {
            return null;
        }

        AggregatedPage<DocBean> queryForPage = elasticsearchTemplate.queryForPage(searchQuery, DocBean.class,
                new SearchResultMapper() {

                    @Override
                    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz,
                                                            Pageable pageable) {

                        List<DocBean> list = new ArrayList<DocBean>();
                        for (SearchHit searchHit : response.getHits()) {
                            if (response.getHits().getHits().length <= 0) {
                                return null;
                            }
                            DocBean DocBean = JSONObject.parseObject(searchHit.getSourceAsString(), DocBean.class);
                            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                            //匹配到的content字段里面的信息
                            HighlightField contentHighlight = highlightFields.get("content");
                            if (contentHighlight != null) {
                                Text[] fragments = contentHighlight.fragments();
                                String fragmentString = fragments[0].string();
                                DocBean.setContent(fragmentString);
                            }
                            list.add(DocBean);

                        }
                        if (list.size() > 0) {
                            return new AggregatedPageImpl<T>((List<T>) list);
                        }
                        return null;
                    }

                    @Override
                    public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
                        return null;
                    }
                });
        return queryForPage;
    }
在这里插入图片描述
在这里插入图片描述
Gitee

gitee地址

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. pom
  • 2.application.properties
  • 3.实体类
  • 4.dao
  • 5.service
  • 6.ctrl
  • 7.测试
  • 8.高亮显示
  • Gitee
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档