Lucene + Pinyin4J 提供首字母搜索(——)
遇到一個集團需求,要求在地址查詢時候提供拼音搜索,第一反應應該不難,不過實現過程中卻一波三折。
1、第一步是講字段首字母進行索引,具體可以使用Pinyin4j提供的方法完成。
2、原來系統用的lucene3.0,分詞用的ikanalyzer3.2 ,不支持連續字母和數字的分詞,網上搜索下 ikanalyzer5.2 可以支持,下載下來發現必須用1.7JDK,如此高的版本,實際上已經把采納的可能槍斃了。然後進行測試,發現仍然不行。最後找到 WildcardQuery 查詢;具體代碼如下
Boolean isPingYin = false;
if(firstCharacter.matches("^[A-Za-z]+$")){
isPingYin = true;
}
if(isPingYin) {
if(tempStandName.length()<4) {
return list;
}
WildcardQuery wq=new WildcardQuery(new Term("standNamePingyin","*" + tempStandName + "*"));
BooleanQuery booleanQuery = new BooleanQuery();
booleanQuery.add(wq, Occur.MUST);
TermQuery termQuery1 = new TermQuery(new Term("outSide", "0"));
booleanQuery.add(termQuery1, Occur.MUST);
TermQuery termQuery2 = new TermQuery(new Term("bindEqps", "1"));
booleanQuery.add(termQuery2, Occur.MUST);
/**
* 模糊查詢器
*/
TopDocs topDocs_pp = isearcher.search(booleanQuery, count);
ScoreDoc[] scoreDocs_pp = topDocs_pp.scoreDocs;
for (int i = 0; i < (topDocs_pp.totalHits > count ? count : topDocs_pp.totalHits); i++)
{
VOqryAddrSegm voQAS = new VOqryAddrSegm();
Document targetDoc = isearcher.doc(scoreDocs_pp[i].doc);
voQAS.setSegmID(targetDoc.get("segmId"));
voQAS.setStandName(targetDoc.get("standName"));
voQAS.setSegmType(targetDoc.get("segmType"));
voQAS.setRegionId(targetDoc.get("regionId"));
voQAS.setBindEqps(targetDoc.get("bindEqps"));
voQAS.setOutSide(targetDoc.get("outSide"));
list.add(voQAS);
}
}
實現的效果:
Lucene + Pinyin4J 提供首字母搜索(——)