美文网首页
热点平台搭建(四)——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

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

  • 18.8.22课

    线上平台引流的主要成本是广告,线下是房租。线上平台通过直播答题、直播热点话题等方式引流,线下商场通过打折促销、搭建...

  • 平台(现代诗)

    平台是你 搭建的 借我 站上去 看世界 平台是你 搭建的 借我 站上去 平台是你 搭建的 借我 平台是你 搭建的 ...

  • 热点平台搭建(三)——Springboot+Mybatis+My

    entity 与Mysql中表相对应: 使用lombok省略构造方法,get与set方法的编写。因为不同网站的热点...

  • 热点平台搭建(二)——MySQL表及Elasticsearch

    MySQL中数据表创建 有第一张表后创建其他相同类型的表: Elasticsearch mapping设置 更新I...

  • 2022-12-17

    1、需要提升的敏锐度: 1)热点敏锐度——时间节点热点、行业热点 2)平台敏锐度——了解平台规则 3)项目敏锐度—...

  • 基于宜搭的《T恤尺码收集》应用搭建

    一、产品介绍 宜搭:人人搭建、人人使用。应用搭建,从未如此简单。 宜搭平台的命名取适宜搭建、容易搭建之意。平台集合...

  • 输出力大学64讲 公众号盈利模式之软文

    今天的作业是根据自己目前所在的平台 比如公众号、头条号还是知乎,挑一个热点,围绕热点创作的四个方法,取四个不同形式...

  • 博客分享计划

    《核心分享--数据平台搭建》 这既是数据平台搭建的核心点,也是接下来个人文章分享之旅的开始,会以平台搭建为基础,在...

  • 关联AndroidStudio和自己本地SonarQube平台

    首先搭建SonarQube平台可以参照:SonarQube的Android环境配置前半段搭建平台,后半段在连接平台...

网友评论

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

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