Java使用IKAnalyzer實現多關鍵字查詢

前端時間公司內部開發了一個小項目,方便運維人員在線上傳查閱資料,其中搜索功能提出要實現 多關鍵字 結果高亮顯示。

剛好想到之前項目使用過IKAnalyzer語義分析實現詞雲的效果,剛好能用在這裏,於是有了以下思路:

1、創建一個list(數組、set都行);

2、加入整個搜索字條作爲基礎搜索條件;

3、走語義分析,拆分成小的詞組,list中沒有時加入;

4、遍歷出所有結果;

最後對返回的關鍵字全局替換成高亮顯示。

效果展示:

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>");
        });
    }

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章