BBS论坛项目相关-12:ES搜索相关

本文介绍了BBS论坛项目中使用Elasticsearch进行搜索的相关内容,包括Elasticsearch的基本概念、Spring与Elasticsearch的整合,以及如何实现搜索功能。涉及到索引创建、删除,以及Spring Data Elasticsearch在服务层和控制器层的应用,如保存、删除和搜索帖子,并通过事件监听实现实时同步数据库和ES的数据。
摘要由CSDN通过智能技术生成

BBS论坛项目相关-12:ES搜索相关

ElasticSearch

Elasticsearch:分布式的Restful风格的搜索引擎
搜索速度快,可提供实时的搜索服务,便于水平扩展,每秒可以处理PB级海量数据
相关术语:
索引,类型,文档,字段
集群,节点,分片,副本
Springboot中声明的ES版本为6.4.3,9200端口
可以在IKAnalyzer.cfg.xml配置自己的dic字典文件
curl -X PUT “localhost:9200/test” 添加索引—返回json格式
curl -X GET “localhost:9200/_cat/indeces?v” 查找
curl -X DELETE “localhost:9200/test” 删除
POSTMAN

Spring整合Elasticsearch

引入依赖:spring-boot-starter-data-elasticsearch
配置Elasticsearch: cluster-name。cluster-nodes
spring.data.elasticsearch.cluster-name=nowcoder
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
Elasticsearch有两个端口,9200是http访问端口,9300是tcp端口
Redis和Elasticsearch底层都基于netty,在启动netty时会产生冲突,nettyRuntime默认如果已经调用,就不能再调用,所以Redis启动netty后,Elasticsearch再调用会认为netty已经启动就不再启动进而产生报错。所以在初始化中要将netty4utils中set设为false,(让他不再执行依赖扫描?)让netty可以被重复依赖。

@SpringBootApplication
public class CommunityApplication {
   

    @PostConstruct//初始化回调方法
    public void init() {
   
        // 解决netty启动冲突问题
        // see Netty4Utils.setAvailableProcessors()
        System.setProperty("es.set.netty.runtime.available.processors", "false");
    }

    public static void main(String[] args) {
   
        SpringApplication.run(CommunityApplication.class, args);
    }
}

Spring Data Elasticsearch:ElasticsearchTemplate ElasticsearchRepository
把数据库中存储的帖子存在ES中,通过ElasticsearchRepository,spring自动生成,生成之前需要做一些配置,告诉它表和索引之间的对应关系,用什么方法实现搜索等,用注解实现
analyzer = "ik_max_word"尽可能分成多的单词;
searchAnalyzer = "ik_smart"搜索时尽量符合搜索时的词,尽量少分词

@Document(indexName = "discusspost", type = "_doc", shards = 6, replicas = 3)
public class DiscussPost {
   
    @Id
    private int id;

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

    // 互联网校招
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String title;

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

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

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

    @Field(type = FieldType.Date)
    private Date createTime;

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

    @Field(type = FieldType.Double)
    private double score;
}

@Repository针对数据访问层的接口
定义一个接口实现ElasticsearchRepository并指定泛型,接口要处理的实体类和主键类型
在索引中保存数据可直接调用discussRepository.save(discussMapper.selectDiscussPostById(241));

@Repository
public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost, Integer> {
   
}

利用repository进行搜索,ES能把关键字高亮,将返回的关键词前后加上标签。
可通过NativeSearchQueryBuilder自定义搜索功能,设置搜索的关键词,以及搜索结果排序等,按分页条件查询,以及高亮显示等

 @Test
    public void testSearchByRepository() {
   
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))
                .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
                .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
                .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
                .withPageable(PageRequest.of(0, 10))
                .withHighlightFields(
                        new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
                        new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")
                ).build();

        // elasticTemplate.queryForPage(searchQuery, class, SearchResultMapper)
        //Repository底层查到的数据用SearchResultMapper进行处理,要把两份数据组装在一起需要用mapper进行处理。
        // Repository底层获取得到了高亮显示的值, 但是没有返回.

        Page<DiscussPost> page = discussRepository.search(searchQuery);
        System.out.println(page.getTotalElements());
        System.out.println(page.getTotalPages());
        System.out.println(page.getNumber());
        System.out.println(page.getSize());
        for (DiscussPost post : page) {
   
            System.out.println(post);
        }
    }

用template方法实现高亮,查询到结果后用mapper进行处理

@Test
    public void testSearchByTemplate() {
   
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))
                .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
                .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
                .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
                .withPageable(PageRequest.of(0, 10))
                .withHighlightFields(
                        new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
                        new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值