問題描述
我寫了一個搜索的小項目,想利用es來實現高亮搜索,但是突然發現,我的搜索功能,只能搜出來英文譬如java,dior,vue等等,但是像醫學,高等數學就搜不出來了!
解決思路
一開始,我以爲是我的請求發送過去導致了中文亂碼
new Vue({
el:'#app',
data:{
keyword:'' ,//搜索的關鍵字
results:[] //搜索的結果
},
methods:{
searchKey(){
var keyword = this.keyword;
console.log(keyword);
//對接後端接口
axios.get('search/'+keyword+"/1/20").then(response=>{
console.log(response);
//綁定數據
this.results = response.data;
})
}
}
})
我以爲我的後臺收到的請求keyword搜索關鍵字亂碼了,但是後臺打印一下發現並沒有亂碼!!
再次尋找解決思路
我後來查閱資料好像說是分詞器的問題!!!誒,有道理
我就試了試單搜一個“醫”字或者“學”發現真能搜出來,那麼也就有一點眉目了,但是這個分詞器要改麼?我一開始覺得是詞庫沒有醫學之類的詞語,天真!!人家詞庫量太大,不可能沒有醫學兩個字的詞語,然後就問大佬,看博客,後來找到了一片類似的博客
老哥的原連接:https://blog.csdn.net/qq_44961149/article/details/107300665
有興趣的可以去看一下
原因出在:
//實現搜索功能
public List<Map<String,Object>> searchPage(String keyword,int pageNo,int pageSize) throws IOException {
if (pageNo<1){
pageNo = 1;
}
//條件搜索
SearchRequest searchRequest = new SearchRequest("jd_goods");
//構建搜索條件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//實現分頁功能
searchSourceBuilder.from(pageNo);
searchSourceBuilder.size(pageSize);
//精確匹配
// TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title",keyword);
MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("title", keyword);
searchSourceBuilder.query(matchPhraseQueryBuilder);
//60s加載時間
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");
//這裏可以配置多個字段,信息等等
//關閉多個高亮
highlightBuilder.requireFieldMatch(false);
highlightBuilder.preTags("<span style='color:red'>");
highlightBuilder.postTags("</span>");
searchSourceBuilder.highlighter(highlightBuilder);
//執行搜索
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//解析結果
ArrayList<Map<String,Object>> list = new ArrayList<>();
for (SearchHit documentFields : searchResponse.getHits().getHits()) {
//解析我們的高亮字段
Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
HighlightField title = highlightFields.get("title");
//原來的結果
Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
if (documentFields != null)
{
Text[] fragments = title.fragments();
String n_title = "";
//將高亮替換原來的字段
for (Text text : fragments) {
n_title += text;
}
sourceAsMap.put("title",n_title);
}
list.add(sourceAsMap);
}
return list;
}
//精確匹配
// TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(“title”,keyword);
MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery(“title”, keyword);
這一點當初看視頻學的時候有一些印象,說是term不會分詞。而keyword字段也不分詞,但是我呢加載了ik分詞器,ik分詞器是會默認分詞的,所以不能再使用TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(“title”,keyword);這種方法了,應該換成 MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery(“title”, keyword);完全匹配的模式!!!
學到了,有更深理解的交流下!!!!