ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

论坛项目进展06

2022-06-20 20:35:45  阅读:118  来源: 互联网

标签:06 String 进展 private toString 论坛 new post type


第6章 Elasticsearch,分布式搜索引擎
6.1 Elasticsearch入门

image-20220620181139084

6.2 Spring整合Elasticsearch

image-20220620182555051

把数据库里的帖子存到es服务器里,然后从es服务器里去搜索.

在DiscussPost实例类上加上:

@Document(indexName = "discusspost", type = "_doc", shards = 6, replicas = 3)//会自动将实体数据和es服务器里面的索引做映射,discusspost是索引名,shards为分片,分6片。replicas表示副本,备份三份。
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;
   。。。。。
}

访问es和访问mysql不一样,所以在dao包下建一个子包elasticsearch,在其下建DiscussPostRepository:

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

}
6.3 开发社区搜索功能

image-20220620194738347

service增加:ElasticsearchService

@Service
public class ElasticsearchService {
   @Autowired
   private DiscussPostRepository discussRepository;
   @Autowired
   private ElasticsearchTemplate elasticTemplate;
   public void saveDiscussPost(DiscussPost post) {
       discussRepository.save(post);
  }
   public void deleteDiscussPost(int id) {
       discussRepository.deleteById(id);
  }
   public Page<DiscussPost> searchDiscussPost(String keyword, int current, int limit) {
       SearchQuery searchQuery = new NativeSearchQueryBuilder()
              .withQuery(QueryBuilders.multiMatchQuery(keyword, "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(current, limit))
              .withHighlightFields(
                       new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
                       new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")
              ).build();

       return elasticTemplate.queryForPage(searchQuery, DiscussPost.class, new SearchResultMapper() {
           @Override
           public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) {
               SearchHits hits = response.getHits();
               if (hits.getTotalHits() <= 0) {
                   return null;
              }
               List<DiscussPost> list = new ArrayList<>();
               for (SearchHit hit : hits) {
                   DiscussPost post = new DiscussPost();
                   String id = hit.getSourceAsMap().get("id").toString();
                   post.setId(Integer.valueOf(id));
                   String userId = hit.getSourceAsMap().get("userId").toString();
                   post.setUserId(Integer.valueOf(userId));
                   String title = hit.getSourceAsMap().get("title").toString();
                   post.setTitle(title);
                   String content = hit.getSourceAsMap().get("content").toString();
                   post.setContent(content);
                   String status = hit.getSourceAsMap().get("status").toString();
                   post.setStatus(Integer.valueOf(status));
                   String createTime = hit.getSourceAsMap().get("createTime").toString();
                   post.setCreateTime(new Date(Long.valueOf(createTime)));
                   String commentCount = hit.getSourceAsMap().get("commentCount").toString();
                   post.setCommentCount(Integer.valueOf(commentCount));
                   // 处理高亮显示的结果
                   HighlightField titleField = hit.getHighlightFields().get("title");
                   if (titleField != null) {
                       post.setTitle(titleField.getFragments()[0].toString());
                  }
                   HighlightField contentField = hit.getHighlightFields().get("content");
                   if (contentField != null) {
                       post.setContent(contentField.getFragments()[0].toString());
                  }
                   list.add(post);
              }
               return new AggregatedPageImpl(list, pageable,
                       hits.getTotalHits(), response.getAggregations(), response.getScrollId(), hits.getMaxScore());
          }
      });
  }
}

在DiscussPostController的addDiscussPost发帖方法和CommentController的addComment分别加上:

        // 触发发帖事件
       Event event = new Event()
              .setTopic(TOPIC_PUBLISH)
              .setUserId(user.getId())
              .setEntityType(ENTITY_TYPE_POST)
              .setEntityId(post.getId());
       eventProducer.fireEvent(event);
if (comment.getEntityType() == ENTITY_TYPE_POST) {
           // 触发发帖事件
           event = new Event()
                  .setTopic(TOPIC_PUBLISH)
                  .setUserId(comment.getUserId())
                  .setEntityType(ENTITY_TYPE_POST)
                  .setEntityId(discussPostId);
           eventProducer.fireEvent(event);

在EventConsumer中加上:

 // 消费发帖事件
   @KafkaListener(topics = {TOPIC_PUBLISH})
   public void handlePublishMessage(ConsumerRecord record) {
       if (record == null || record.value() == null) {
           logger.error("消息的内容为空!");
           return;
      }
       Event event = JSONObject.parseObject(record.value().toString(), Event.class);
       if (event == null) {
           logger.error("消息格式错误!");
           return;
      }
       DiscussPost post = discussPostService.findDiscussPostById(event.getEntityId());
       elasticsearchService.saveDiscussPost(post);//把查到的帖子存到es服务器里
  }

新建SearchController

@Controller
public class SearchController implements CommunityConstant {
   @Autowired
   private ElasticsearchService elasticsearchService;
   @Autowired
   private UserService userService;
   @Autowired
   private LikeService likeService;
   // search?keyword=xxx
   @RequestMapping(path = "/search", method = RequestMethod.GET)
   public String search(String keyword, Page page, Model model) {
       // 搜索帖子
       org.springframework.data.domain.Page<DiscussPost> searchResult =
               elasticsearchService.searchDiscussPost(keyword, page.getCurrent() - 1, page.getLimit());
       // 聚合数据
       List<Map<String, Object>> discussPosts = new ArrayList<>();
       if (searchResult != null) {
           for (DiscussPost post : searchResult) {
               Map<String, Object> map = new HashMap<>();
               // 帖子
               map.put("post", post);
               // 作者
               map.put("user", userService.findUserById(post.getUserId()));
               // 点赞数量
               map.put("likeCount", likeService.findEntityLikeCount(ENTITY_TYPE_POST, post.getId()));
               discussPosts.add(map);
          }
      }
       model.addAttribute("discussPosts", discussPosts);
       model.addAttribute("keyword", keyword);
       // 分页信息
       page.setPath("/search?keyword=" + keyword);
       page.setRows(searchResult == null ? 0 : (int) searchResult.getTotalElements());
       return "/site/search";
  }
}


标签:06,String,进展,private,toString,论坛,new,post,type
来源: https://www.cnblogs.com/zhangshuai2496689659/p/16394601.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有