美文网首页
热点平台搭建(四)——Springboot+Elasticsea

热点平台搭建(四)——Springboot+Elasticsea

作者: 请不要问我是谁 | 来源:发表于2020-03-11 20:45 被阅读0次

    使用Elasticsearch查询历史热点消息,搜索的内容包括:根据关键词搜索,可以多个关键词;根据热点标题查找历史热度值变化。

    搜索框DTO

    用来接收前端传递的搜索框内容。

    @Data
    public class SearchKeywords {
        @NotEmpty
        private String keywords;
        @NotEmpty
        private String relation;
        @NotEmpty
        @NotNull
        private String type;
    }
    

    定义SeachData接收从ES返回的数据

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class SearchData {
        private String titleText;
        private String titleKeyword;
        private Integer rank;
        private Integer hotNumber;
        private String timestamp;
        private Integer uId;
    }
    

    服务接口

    public interface SearchService {
        /**
         * 根据标题查找历史信息
         * @param title 标题
         * @param type 哪个表
         * @return 历史信息
         */
        public List<SearchData> searchByName(String title, String type);
    
        /**
         * 根据关键词查找
         * @param keyword 关键词
         * @param type 表名
         * @param relation 关键词之间的关系
         * @return 历史信息
         */
        public List<SearchData> searchByKeyword(String keyword, String type, String relation);
    
        /**
         * 根据uId查找内容详情
         * @param type 热榜名称
         * @param uId 唯一键
         * @return 详情
         */
        public List<SearchDetail> searchDetail(String type, int uId);
    }
    

    包括两个查询内容,还包含了一个根据uId查找历史消息,uId在数据库中建立了索引。

    服务实现

    @Service
    public class SearchServiceImpl implements SearchService {
    
        @Autowired
        private EsUtil esUtil;
    
        @Autowired
        private SearchDetailMapper searchDetailMapper;
    
        @Override
        public List<SearchData> searchByName(String title, String type) {
            // 创建bool query
            BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
            // 查找title_keyword中有查找的关键词
            boolQueryBuilder.filter(QueryBuilders.termQuery("title_keyword", title));
            SearchSourceBuilder builder = new SearchSourceBuilder();
            builder.query(boolQueryBuilder);
            // 根据时间倒序
            builder.sort("timestamp", SortOrder.ASC);
            // 取前30个
            builder.size(30);
            return esUtil.search(type+"_data", builder, SearchData.class);
        }
    
        @Override
        public List<SearchData> searchByKeyword(String keyword, String type, String relation) {
            // 创建simple query string
            SimpleQueryStringBuilder simpleQueryStringBuilder = new SimpleQueryStringBuilder(keyword);
            // 根据title_text匹配
            simpleQueryStringBuilder.field("title_text");
            // 关键词关系有和与或
            if("OR".equals(relation) || "or".equals(relation)){
                simpleQueryStringBuilder.defaultOperator(Operator.OR);
            }else {
                simpleQueryStringBuilder.defaultOperator(Operator.AND);
            }
            SearchSourceBuilder builder = new SearchSourceBuilder();
            builder.query(simpleQueryStringBuilder);
            builder.sort("timestamp", SortOrder.DESC);
            // 找出历史排序最高的一条
            CollapseBuilder collapseBuilder = new CollapseBuilder("title_keyword");
            InnerHitBuilder innerHitBuilder = new InnerHitBuilder("top_hot");
            innerHitBuilder.setSize(1);
            SortBuilder sortBuilder = SortBuilders.fieldSort("hot_number").order(SortOrder.DESC);
            innerHitBuilder.addSort(sortBuilder);
            collapseBuilder.setInnerHits(innerHitBuilder);
            builder.collapse(collapseBuilder);
            builder.size(30);
            return esUtil.search(type+"_data", builder, SearchData.class);
        }
    
        @Override
        public List<SearchDetail> searchDetail(String type, int uId) {
            return searchDetailMapper.queryDetail(type, uId);
        }
    }
    

    EsUtil

    ES实现工具类

    @Component
    public class EsUtil {
        @Value("${es.host}")
        private String host;
        @Value("${es.port}")
        private int port;
        @Value("${es.scheme}")
        private String scheme;
    
        private static RestHighLevelClient client = null;
    
        @PostConstruct
        public void init() {
            try {
                if (client != null) {
                    client.close();
                }
                client = new RestHighLevelClient(RestClient.builder(new HttpHost(host, port, scheme)));
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
    
        /**
         * Description: 搜索
         *
         * @param index   index
         * @param builder 查询参数
         * @param c       结果类对象
         * @return java.util.ArrayList
         * @author fanxb
         * @date 2019/7/25 13:46
         */
        public <T> List<T> search(String index, SearchSourceBuilder builder, Class<T> c) {
            SearchRequest request = new SearchRequest(index);
            request.source(builder);
            try {
                SearchResponse response = client.search(request, RequestOptions.DEFAULT);
                SearchHit[] hits = response.getHits().getHits();
                List<T> res = new ArrayList<>(hits.length);
                for (SearchHit hit : hits) {
                    res.add(JSON.parseObject(hit.getSourceAsString(), c));
                }
                return res;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
    

    Controller

    @Controller
    @RequestMapping("/search")
    public class searchController {
    
        private static Logger logger = LoggerFactory.getLogger(IndexController.class);
    
        @Resource
        SearchService searchService;
    
        @RequestMapping(value = "/searchTitle", method = RequestMethod.GET)
        public String searchTitle(@RequestParam(value = "title") String title, @RequestParam(value = "type") String type ,ModelMap map){
            UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            String name = userDetails.getUsername();
            logger.info("用户名=" + name + "&行为=历史热度查看:" + title + "|" + type);
    
            map.addAttribute("titleData", title);
            List<String> time = new ArrayList<>();
            List<Integer> hotNumber = new ArrayList<>();
            List<SearchData> hotSpots = searchService.searchByName(title, type);
            for (SearchData hotSpot: hotSpots){
                time.add(hotSpot.getTimestamp().replace('T', ' '));
                hotNumber.add(hotSpot.getHotNumber());
            }
            map.addAttribute("timeData", time);
            map.addAttribute("hotNumberData", hotNumber);
            return "search/searchTitle";
        }
    
        @RequestMapping(value = "/searchDetail", method = RequestMethod.GET)
        @ResponseBody
        public SearchDetail searchDetail(@RequestParam(value = "uId") int uId, @RequestParam(value = "type") String type ,ModelMap map){
            UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            String name = userDetails.getUsername();
            logger.info("用户名=" + name + "&行为=详情查看:" + uId + "|" + type);
            List<SearchDetail> searchDetails = searchService.searchDetail(type, uId);
            return searchDetails.get(0);
        }
    
        @PostMapping(value = "/searchKeywords")
        public String searchKeywords(@ModelAttribute("searchKeywords") @Valid SearchKeywords searchKeywords, BindingResult result, Model model){
            UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            String name = userDetails.getUsername();
            logger.info("用户名=" + name + "&行为=关键词查找:" + searchKeywords.getKeywords() + "|" + searchKeywords.getType() + "|" + searchKeywords.getRelation());
    
            if (result.hasErrors()){
                return "search/searchKeywords";
            }
            String type = getTypeName(searchKeywords.getType());
            List<SearchData> searchHotSpotData = searchService.searchByKeyword(searchKeywords.getKeywords(), type, searchKeywords.getRelation());
            model.addAttribute("searchHotSpotData", searchHotSpotData);
            model.addAttribute("dataType", type);
            return "search/searchKeywords";
        }
    
        @GetMapping(value = "/searchKeywords")
        public String toSearchKeywords(Model model){
            model.addAttribute("searchKeywords", new SearchKeywords());
            return "search/searchKeywords";
        }
    
        private String getTypeName(String type) {
            switch (type){
                case "微博":
                    return "weibo";
                case "牛客":
                    return "niuke";
                case "虎扑":
                    return "hupu";
                case "掘金":
                    return "juejin";
                default:
                    return "weibo";
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:热点平台搭建(四)——Springboot+Elasticsea

          本文链接:https://www.haomeiwen.com/subject/nwahjhtx.html