您好,登錄后才能下訂單哦!
這篇文章主要講解了“Lucene的Suggest怎么使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Lucene的Suggest怎么使用”吧!
lucene的聯想詞是在org.apache.lucene.search.suggest包下邊,提供了自動補全或者聯想提示功能的支持。
<!-- 搜索提示 --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-suggest</artifactId> <version>7.2.1</version> </dependency>
@RestController @RequestMapping(value = "/suggest") public class SuggestController { @Resource private SuggestService suggestService; /** * 推薦詞搜索 * @param keyword * @return */ @GetMapping(value = "/searchSuggest") public List<DictionaryVO> searchSuggest(String keyword) { return suggestService.searchSuggest(keyword); } } 訪問地址: localhost:2000/spring-master/suggest/searchSuggest?keyword=胃造
@Slf4j @Service public class SuggestServiceImpl implements SuggestService { private AnalyzingInfixSuggester suggester; /** * 內存存儲:優點速度快,缺點程序退出數據就沒了 */ protected RAMDirectory directory; /** * 索引分詞 */ protected StandardAnalyzer indexAnalyzer; /** * 查詢分詞 */ protected StandardAnalyzer queryAnalyzer; @Override public List<DictionaryVO> searchSuggest(String keyword) { List dictionaryList = new ArrayList(); HashSet<BytesRef> contexts = new HashSet<BytesRef>(); // 先根據region域進行suggest,再根據name域進行suggest // contexts.add(new BytesRef(region.getBytes("UTF8"))); // num決定了返回幾條數據,參數四表明是否所有TermQuery是否都需要滿足,參數五表明是否需要高亮顯示 int num = 10; try { List<Lookup.LookupResult> results = suggester.lookup(keyword, num, true, false); for (Lookup.LookupResult result : results) { // result.key中存儲的是根據用戶輸入內部算法進行匹配后返回的suggest內容 log.info("result_key: " + result.key); // 從載荷(payload)中反序列化出Product對象(實際生產中出于降低內存占用考慮一般不會在載荷中存儲這么多內容) BytesRef bytesRef = result.payload; ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytesRef.bytes)); try { DictionaryVO dictionaryVO = (DictionaryVO) objectInputStream.readObject(); dictionaryList.add(dictionaryVO); } catch (ClassNotFoundException cnfe) { log.error(cnfe.getMessage()); } } } catch (Exception e) { log.error(e.getMessage()); } return dictionaryList; } /** * 初始化詞典 * @return */ @PostConstruct protected void initSuggest() { directory = new RAMDirectory(); indexAnalyzer = new StandardAnalyzer(); queryAnalyzer = new StandardAnalyzer(); try { suggester = new AnalyzingInfixSuggester(directory, indexAnalyzer, queryAnalyzer, AnalyzingInfixSuggester.DEFAULT_MIN_PREFIX_CHARS, false); long start = System.currentTimeMillis(); // 讀DictionaryVO數據 List diseases = FileUtils.readCsv(SuggestConstants.disease); List facultys = FileUtils.readCsv(SuggestConstants.faculty); List hospitals = FileUtils.readCsv(SuggestConstants.hospital); List drugcatalogues = FileUtils.readCsv(SuggestConstants.drugcatalogue); List doctors = FileUtils.readCsv(SuggestConstants.doctor); List allTerms = new ArrayList(); allTerms.addAll(facultys); allTerms.addAll(hospitals); allTerms.addAll(diseases); allTerms.addAll(drugcatalogues); allTerms.addAll(doctors); // 創建索引,根據InputIterator的具體實現決定數據源以及創建索引的規則 suggester.build(new DictionaryIterator(allTerms.iterator())); suggester.commit(); long end = System.currentTimeMillis(); log.info("It takes time to initialize the dictionary:" + (end - start)); this.initAfter(); } catch (IOException io) { log.error(io.getMessage()); } } protected void initAfter() { } /** * 銷毀詞典 */ @PreDestroy protected void destroy(){ try { if(suggester != null) { suggester.close(); } if(directory != null) { directory.close(); } } catch (IOException e) { log.error(e.getMessage(), e); } if(indexAnalyzer != null) { indexAnalyzer.close(); } if(queryAnalyzer != null) { queryAnalyzer.close(); } this.destroyAfter(); } protected void destroyAfter(){ } }
@Slf4j public class FileUtils { /** * 讀取詞典csv文件 * @param fileNamePath * @return */ public static List<DictionaryVO> readCsv(String fileNamePath) { List<DictionaryVO> dictionarys = new ArrayList<>(); try { // 換成你的文件名 BufferedReader reader = new BufferedReader(new FileReader(fileNamePath)); String line; while ((line = reader.readLine()) != null) { // CSV格式文件為逗號分隔符文件,這里根據逗號切分 String[] item = line.split(","); dictionarys.add(new DictionaryVO(item[0], item[1], Long.parseLong(item[2]), Long.parseLong(item[3]))); } } catch (Exception e) { e.printStackTrace(); log.error(e.getMessage()); } return dictionarys; } }
package com.spring.master.lucene.suggest.core; import com.spring.master.lucene.suggest.vo.DictionaryVO; import org.apache.lucene.search.suggest.InputIterator; import org.apache.lucene.util.BytesRef; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.UnsupportedEncodingException; import java.util.Iterator; import java.util.Set; /** * @author Huan Lee * @version 1.0 * @date 2020-09-10 14:55 * @describtion 核心類:決定了你的索引是如何創建的,決定了最終返回的提示關鍵詞列表數據及其排序 * */ public class DictionaryIterator implements InputIterator { private Iterator<DictionaryVO> dictionaryIterator; private DictionaryVO currentDictionary; public DictionaryIterator(Iterator<DictionaryVO> dictionaryIterator) { this.dictionaryIterator = dictionaryIterator; } @Override public long weight() { // TODO 這里可以設置權重 return currentDictionary.getWeight(); return 1; } /** * 將DictionaryVO對象序列化存入payload * @return */ @Override public BytesRef payload() { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(currentDictionary); out.close(); return new BytesRef(bos.toByteArray()); } catch (IOException e) { throw new RuntimeException("Well that's unfortunate."); } } @Override public boolean hasPayloads() { return true; } /** * 設置是否啟用Contexts域 * @return */ @Override public boolean hasContexts() { return false; } /** * 獲取某個term的contexts,用來過濾suggest的內容,如果suggest的列表為空,返回null * @return */ @Override public Set<BytesRef> contexts() { // try { // Set<BytesRef> regions = new HashSet<>(); // regions.add(new BytesRef(currentDictionary.getSourceType().getBytes("UTF8"))); // return regions; // } catch (UnsupportedEncodingException e) { // throw new RuntimeException("Couldn't convert to UTF-8"); // } return null; } @Override public BytesRef next() throws IOException { if (dictionaryIterator.hasNext()) { currentDictionary = dictionaryIterator.next(); try { //返回當前Project的name值,把product類的name屬性值作為key return new BytesRef(currentDictionary.getWord().getBytes("UTF8")); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Couldn't convert to UTF-8",e); } } else { return null; } } }
@Data public class DictionaryVO implements Serializable { public DictionaryVO() { } public DictionaryVO(String word, String sourceType, Long sourceId, Long weight) { this.word = word; this.sourceId = sourceId; this.sourceType = sourceType; this.weight = weight; } /** * 詞典 */ private String word; /** * 來源id */ private Long sourceId; /** * 來源:Doctor、Disease、Hospital、Faculty、Drugcatalogue */ private String sourceType; /** * 權重 */ private Long weight; }
public class SuggestConstants { public static final String faculty = "/Users/lihuan/Documents/projects/git/me/faculty.csv"; public static final String hospital = "/Users/lihuan/Documents/projects/git/me/hospital.csv"; public static final String disease = "/Users/lihuan/Documents/projects/git/me/disease.csv"; public static final String drugcatalogue = "/Users/lihuan/Documents/projects/git/me/drugcatalogue.csv"; public static final String doctor = "/Users/lihuan/Documents/projects/git/me/doctor.csv"; }
感謝各位的閱讀,以上就是“Lucene的Suggest怎么使用”的內容了,經過本文的學習后,相信大家對Lucene的Suggest怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。