初学搜索引擎,简要记录下 lucene7.1.0 搜索流程。
1、现有待处理文件目录D:\test\resource ;
2、通过 lucene 建立索引文件目录 D:\test\index ;
3、在索引目录中搜索关键字。
实现一个简单的demo 步骤如下:
1)下载jar,gradle 配置如下:
compile group: 'org.apache.lucene', name: 'lucene-core', version: '7.1.0'
compile group: 'org.apache.lucene', name: 'lucene-analyzers-common', version: '7.1.0'
2) 创建索引目录
分词器 可以选用 StandardAnalyzer ,SmartChineseAnalyzer(需要下载对应的jar),jcseg (需要下载对应的jar)
@CompileStatic @TypeChecked class IndexProcessor { //索引存储目录 private String indexStorePath = "D:\\test\\index" //创建索引 void createIndex(String inputDir) { try { Directory indexDirectory = FSDirectory.open(new File(indexStorePath).toPath()) //中文分词器 // SmartChineseAnalyzer analyzer=new SmartChineseAnalyzer() // Analyzer analyzer = new JcsegAnalyzer(JcsegTaskConfig.COMPLEX_MODE) //英文、中文 分词器 Analyzer analyzer = new StandardAnalyzer() IndexWriterConfig config = new IndexWriterConfig(analyzer) //利用分词工具创建 IndexWriter IndexWriter writer = new IndexWriter(indexDirectory, config) File filesDir = new File(inputDir) //取得 要建立 索引的文件数组 File[] files = filesDir.listFiles() for (int i = 0; i < files.length; i++) { String fileName = files[i].getName() if (fileName.substring(fileName.lastIndexOf(".")) == ".txt") { //创建新的Document Document doc = new Document() //为文件名创建一个 Field StoredField storedField = new StoredField("filename", files[i].getName()) // Field field = new Field("filename",files[i].getName(),Field.Store.YES) doc.add(storedField) // TextField textField= new TextField("body",new FileReader(files[i])) String body=loadFileToString(files[i]) TextField textField = new TextField("body",body , Field.Store.YES) // field = new Field("content",loadFileToString(files[i]),Field.Store.NO,Field.Index.TOKENIZED) doc.add(textField) //把Document加入 IndexWriter writer.addDocument(doc) } } writer.commit() writer.close() } catch (IOException e) { e.printStackTrace() } } //加载文档 生成字符串 String loadFileToString(File f) { try { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f),"UTF-8")) StringBuffer sb = new StringBuffer() String line = br.readLine() while (line != null) { sb.append(line) line = br.readLine() } br.close() return sb.toString() } catch (IOException e) { e.printStackTrace() return null } } static void main(String[] args) { IndexProcessor pr = new IndexProcessor() pr.createIndex("D:\\test\\resource") } }
执行main 函数 ,生成 索引目录 D:\\test\\index 。
3)在索引目录下 搜索关键词
@CompileStatic @TypeChecked class Search { private String indexStorePath = "D:/test/index" //利用lucene 索引 搜索 public void indexSearch(String searchType, String keyWords) { try { println "##使用索引方式搜索##" Directory indexDirectory = FSDirectory.open(new File(indexStorePath).toPath()) IndexReader indexReader = DirectoryReader.open(indexDirectory) //根据索引位置简历 IndexSearch IndexSearcher searcher = new IndexSearcher(indexReader) // //建立搜索单元,searchType 代表要搜索的Field,searchKey代表关键字 // Term t = new Term(searchType,keyWords) // //由Term产生 Query // Query q = new TermQuery(t) //搜索开始时间 long startTime=System.currentTimeMillis() //中文分词器 // SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer() // Analyzer analyzer = new JcsegAnalyzer(JcsegTaskConfig.COMPLEX_MODE) //英文分词器 Analyzer analyzer = new StandardAnalyzer() QueryParser query_parser = new QueryParser(searchType, analyzer) Query query = query_parser.parse(keyWords) // println "docFreq:"+searcher.count(query) if (searcher != null) { TopDocs result = searcher.search(query, 10) //返回最多为10条记录 println "关键字:" + keyWords + ",在 " + indexStorePath + "中,一共检索到文件 " + result.totalHits+" 个" // ScoreDoc[] hits = result.scoreDocs for (ScoreDoc scoreDoc:hits){ Document document=searcher.doc(scoreDoc.doc) println "关键字:" + keyWords + ",在 " + document.get("filename") + "文件中"+scoreDoc.score } searcher.indexReader.close() } long endTime=System.currentTimeMillis() println "总耗时:"+(endTime-startTime)+" ms" } catch (Exception e) { e.printStackTrace() } } public static void main(String[] args) { Search s = new Search() s.indexSearch("body", "报告") } }
执行main ,返回如下:
##使用索引方式搜索##
关键字:报告,在 D:/test/index中,一共检索到文件 2 个
关键字:报告,在 c1.txt文件中0.672359
关键字:报告,在 c2.txt文件中0.66506714
总耗时:184 ms
OK,一个简单的demo 就完成了。