Lucene library를 이용한 간단한 색인/검색(루씬 라이브러리이용)
2019. 1. 3. 21:07ㆍSearch-Engine/Lucene
Lucene library를 이용한 간단한 색인/검색(루씬 라이브러리이용)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | package com.lucene.study; import java.io.File; import java.io.FileFilter; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; //yeoseong_yoon,2019/1/2->txt파일을 색인하는 유틸클래스 public class Indexer { private IndexWriter writer; //루씬의 IndexWriter 생성 public Indexer(String indexDir) throws IOException { Directory dir = FSDirectory.open(new File(indexDir).toPath()); writer = new IndexWriter(dir,new IndexWriterConfig(new StandardAnalyzer())); } public void close() throws IOException { writer.close(); } public int index(String dataDir,FileFilter filter) throws IOException { File[] files = new File(dataDir).listFiles(); for(File f : files) { if(!f.isDirectory() && !f.isHidden() && f.exists() && f.canRead() && (filter == null || filter.accept(f))) { indexFile(f); } } //색인된 문서건수 리턴 return writer.numDocs(); } private void indexFile(File file) throws IOException { System.out.println("Indexing "+file.getCanonicalPath()); Document doc = getDocument(file); writer.addDocument(doc); } @SuppressWarnings("deprecation") protected Document getDocument(File file) throws IOException { Document doc = new Document(); //파일의 내용추가 doc.add(new Field("content", new FileReader(file))); //파일 이름추가 doc.add(new Field("filename",file.getName(),Field.Store.YES,Field.Index.NOT_ANALYZED)); //파일 전체경로 추가 doc.add(new Field("fullpath",file.getCanonicalPath(),Field.Store.YES,Field.Index.NOT_ANALYZED)); return doc; } //FileFilter를 이용하여 해당 확장자만 걸러낸다. private static class TextFilesFilter implements FileFilter{ public boolean accept(File path) { return path.getName().toLowerCase().endsWith(".txt"); } } public static void main(String[] args) throws IOException { // TODO Auto-generated method stub if(args.length!=2) { throw new IllegalArgumentException("please input index dir & data dir"); } String indexDir = args[0]; String dataDir = args[1]; long start = System.currentTimeMillis(); Indexer indexer = new Indexer(indexDir); int numIndexed = 0; try { numIndexed = indexer.index(dataDir, new TextFilesFilter()); }catch (Exception e) { // TODO: handle exception System.out.println(e.getMessage()); }finally { indexer.close(); } long end = System.currentTimeMillis(); System.out.println("Indexing " + numIndexed + " files took " + (end-start) + " milliseconds"); } } | cs |
=>특정 디렉토리에 들어있는 txt파일을 특정 디렉토리 위치에 색인하는 코드이다.(실행시 arguments로 2개의 인자를 전달해야한다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | package com.lucene.study; import java.io.File; import java.io.IOException; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; public class Searcher { public static void search(String indexDir, String query) throws IOException, ParseException { Directory dir = FSDirectory.open(new File(indexDir).toPath()); //색인을 연다. IndexSearcher indexSearcher = new IndexSearcher(DirectoryReader.open(dir)); //질의를 분석한다. QueryParser parser = new QueryParser("content", new StandardAnalyzer()); Query q = parser.parse(query); long start = System.currentTimeMillis(); TopDocs hits = indexSearcher.search(q, 10); long end = System.currentTimeMillis(); System.out.println("Found "+ hits.totalHits +" document(s) (in "+(end-start) +" millisecond) that matched query '" + q + "' :"); for(ScoreDoc scoreDoc : hits.scoreDocs) { Document doc = indexSearcher.doc(scoreDoc.doc); System.out.println(String.format("content - %s\nfullpath = %s" ,doc.get("content") ,doc.get("fullpath"))); } } public static void main(String[] args) throws IOException, ParseException { // TODO Auto-generated method stub if(args.length !=2) { throw new IllegalArgumentException("please input index dir & search query String"); } String indexDir = args[0]; String query = args[1]; search(indexDir, query); } } | cs |
=>위에서 색인한 색인 목록에서 검색어에 해당하는 문서를 찾는 코드이다. 이도 동일하게 2개의 아규먼트를 전달해야한다.
2개의 간단한 색인/검색을 예제로 짜보았다. 이 코드를 짜기전에 루씬 라이브러리를 dependency 해야하는 선과정이 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!-- START - Lucene Dependencies --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>5.3.0</version> </dependency> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-analyzers-common</artifactId> <version>5.3.0</version> </dependency> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-queryparser</artifactId> <version>5.3.0</version> </dependency> <!-- END - Lucene Dependencies --> | cs |
'Search-Engine > Lucene' 카테고리의 다른 글
Lucene - 인메모리버퍼(In-Memory-Buffer) 역할, 세그먼트 병합(Merge) (0) | 2019.05.25 |
---|---|
Lucene - 유사어,동의어 필터(SynonymFilter)를 이용한 커스텀 Analyzer (0) | 2019.02.02 |
Lucene - 분석기(Analyzer)로 분석한 토큰(Token)결과 출력 (0) | 2019.01.29 |