欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java使用IKAnalyzer实现多关键字查询

程序员文章站 2022-06-02 15:14:00
...

前端时间公司内部开发了一个小项目,方便运维人员在线上传查阅资料,其中搜索功能提出要实现 多关键字 结果高亮显示。

刚好想到之前项目使用过IKAnalyzer语义分析实现词云的效果,刚好能用在这里,于是有了以下思路:

1、创建一个list(数组、set都行);

2、加入整个搜索字条作为基础搜索条件;

3、走语义分析,拆分成小的词组,list中没有时加入;

4、遍历出所有结果;

最后对返回的关键字全局替换成高亮显示。

效果展示:

Java使用IKAnalyzer实现多关键字查询

ps:项目框架使用的SSM

看下代码,接口:

 @RequestMapping("/search.json")
    @ResponseBody
    public Pagination<Article> search(@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                      @RequestParam(name="pageSize", defaultValue="2") Integer pageSize,HttpServletRequest request){
        Pagination<Article> page = new Pagination<>(0, pageSize,pageNo);

        User user = TokenManager.getToken();
        String username = user.getAccount();
        String companyCode = companyEmployeeService.getCompanyByAccount(username);
        Map map=new HashMap(16);
        map.put("company_code",companyCode);

        //用户输入的搜索字符串
        String content=request.getParameter("content");
        try {
            if(StringUtils.isNotEmpty(content)){
                    //创建一个list用于存放切分的关键字,供前台高亮显示
                    List<String> fvs = new ArrayList<>();
                    //整个搜作词条作为默认关键字
                    fvs.add(content);

                    //创建IKAnalyzer实例,设置是否智能分词,扩展词典路径,准备词句拆分
                    MyIKConfig cfg = new MyIKConfig();
                    cfg.setUseSmart(true);
                    cfg.setMainDictionary("ext.dic");
                    IKSegmenter seg = new IKSegmenter(new StringReader(content),cfg);
                    Lexeme word = null;
                    String w = null;
                    //遍历分词,对于重复出现的分词不加入list
                    while((word = seg.next()) != null){
                        w = word.getLexemeText();
                        //切片长度至少为2
                        if(w.length()>1){
                            int nType = word.getLexemeType();
                            if (nType == 64) {
                                continue;
                            }
                            if(!fvs.contains(w)){
                                fvs.add(w);
                            }
                        }
                    }
                    //切分词组加入查询条件
                    map.put("fvs",fvs);
                    //获取所有符合的文章
                    List<Article> articles = articleService.getSearchContent(map,null);
                    //分页查询
                    List<Article> pArticles = articleService.getSearchContent(map,page);
                    //将切分的关键字返回前端(想了半天直接搞了一个临时字段存里面了)
                    if(pArticles!=null && pArticles.size()>0){
                        pArticles.get(0).setIKWords(fvs);
                    }
                    page.setTotalCount(articles.size());
                    page.setTotalPages((int)Math.ceil((double)articles.size()/(double)pageSize));
                    page.setList(pArticles);
            }
            return page;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

Mapper:

  <select id="getSearchContent" parameterType="map" resultType="com.swsc.racoon.entity.Article">
        select distinct a.*,b.value as articleType from se_article a
        left join se_knowledge_tree b on a.article_type=b.dcode
        left join se_company_employee c on c.account =a.create_by
        where a.status='2' and c.company_code = #{company_code}
        <if test="content != null and content != ''">
             AND  (a.title like CONCAT('%',#{content},'%') or a.subtitle like CONCAT('%',#{content},'%'))
        </if>
        <if test="fvs !=null and fvs!=''">
            and
            <foreach collection="fvs" open="(" close=")" separator="or" item="item">
                a.title like CONCAT('%',#{item},'%') or a.subtitle like CONCAT('%',#{item},'%')
            </foreach>
        </if>
         order by a.upload_date desc
    </select>

 

<if test="fvs !=null and fvs!=''">
    and
    <foreach collection="fvs" open="(" close=")" separator="or" item="item">
        a.title like CONCAT('%',#{item},'%') or a.subtitle like CONCAT('%',#{item},'%')
    </foreach>
</if>

这里是Mybatis对于list的foreach循环,结构是 and ( (x like xx or x like xx) or (x like xx or x like xx) or (x like xx or x like xx) ..)

 

前端页面:

高亮展示思路即获取区域元素全局关键字替换

//获取list拼接展示 
$.ajax({
            dataType: 'json',
            type: 'POST',
            url: "/admin/homePage/search.json",
            data: {pageNo: pageNo, content:$("#s_content").val()},
            success: function (data) {
                var html = "";
                //这里是拼接html
                $("#right").html(html);
                for(ele of data.list[0].ikwords){
                    hightLightSearchedContent(ele);
                }
            }
 })
 //高亮显示搜索内容
    function hightLightSearchedContent(otext) {
        $("#right").html(function() {
            var reg = new RegExp(otext,"g");//g,表示全部替换。
            return $(this).html().replace(reg,"<font color=\"red\">"+otext+"</font>");
        });
    }

 

 

相关标签: JAVA_WEB