Elasticsearch 知識分類聚合查詢以及根據字段權重查詢實踐

1.業務背景:首先搜索的內容要首先完全匹配知識分類,並且按關鍵字、摘要、其他字段權重依次減低進行查詢結果按得分從高到低,並對各個知識分類的查詢文檔數進行統計

難點:因爲每個文檔所涉及到的知識分類可能是多個,所以統計的時候,用分類的keyword屬性類型進行聚合查詢就是不可能實現的

2.首先看一下mapping結構

知識分類屬性:File_Clid ,知識關鍵字 :File_KeyWord ,知識摘要:File_Abstract

首先:要對知識分類File_Clid這個用於聚合的屬性,進行分詞測試,fielddata:true表示text類型的字段默認禁用開啓,如果要對這個字段進行聚合和排序等操作時要開啓,加載所對應的的字段的postlist到內存堆中以便進行聚合和排序

因爲File_Clid的值可能是多個知識分類所以keyword肯定就排除掉了,然後測試ik_max_word(不合適)

ik_smart分詞測試(合適)

standard分詞測試(合適)

所以對知識分類File_Clid所用分詞器用ik_smart或者standard

3.kibana查詢

4.上代碼

4.1構建聚合查詢條件
@Override
protected AggregationBuilder buildAggs(JSONObject jsonObject) {
    TermsAggregationBuilder field = AggregationBuilders.terms("知識分類").field("File_Clid");
    return field;
}
4.2構建按權重查詢的條件
@Override
protected QueryBuilder buildQuery(JSONObject jsonObject) {

    BoolQueryBuilder bool = QueryBuilders.boolQuery();
    Object file_clid = jsonObject.get("File_Clid");
    Object content = jsonObject.get("content");
    if(ObjectUtils.isNotEmpty(file_clid))//分類不爲空
        bool.must(QueryBuilders.matchQuery("File_Clid", file_clid.toString()).operator(Operator.AND));
    if(ObjectUtils.isNotEmpty(content)){//查詢內容不爲空按關鍵字、摘要、其他屬性權重
        QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(content.toString());
        Map<String,Float> boost = new HashMap<>();
        boost.put("File_KeyWord",5.0f);//關鍵字
        boost.put("File_Abstract",2.0f);//摘要
        boost.put("File_Title",1.0f);
        boost.put("File_Fun",1.0f);
        boost.put("File_Structure",1.0f);
        boost.put("Principle",1.0f);
        queryStringQueryBuilder.fields(boost);
        bool.must(queryStringQueryBuilder.defaultOperator(Operator.AND));
    }else{//如果查詢內容爲空展示所有的
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        bool.must(matchAllQueryBuilder);
    }
    return bool;
}

4.3查詢

SearchRequestBuilder searchRequestBuilder = esTemplate.getClient().prepareSearch(index)
        .setTypes(type);
if(!aggsisnull)
    searchRequestBuilder.addAggregation(aggs);
if(!queryisnull)
    searchRequestBuilder.setQuery(query);
SearchResponse resp = searchRequestBuilder.get(new TimeValue(30 * 1000));

5.爲了更直觀的看到查詢結果,自己寫了幾個簡單醜陋的頁面

5.1查詢所有{一共插入了7條測試數據,當然文檔沒有完全顯示,截圖知識一部分}

5.2.有查詢內容且結果文檔得分排序

5.3有查詢的分類和內容且結果按得分排序

好了,ok!喜歡的可以點個贊哦...

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