Advertisement
Guest User

Untitled

a guest
Mar 1st, 2017
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.19 KB | None | 0 0
  1. package com.tistory.devyongsik.demo;
  2.  
  3. import org.apache.lucene.analysis.Analyzer;
  4. import org.apache.lucene.analysis.standard.StandardAnalyzer;
  5. import org.apache.lucene.document.Document;
  6. import org.apache.lucene.document.Field;
  7. import org.apache.lucene.document.NumericField;
  8. import org.apache.lucene.index.IndexWriter;
  9. import org.apache.lucene.index.IndexWriterConfig.OpenMode;
  10. import org.apache.lucene.index.IndexWriterConfig;
  11. import org.apache.lucene.index.Term;
  12. import org.apache.lucene.store.Directory;
  13. import org.apache.lucene.store.FSDirectory;
  14. import org.apache.lucene.util.Version;
  15.  
  16. import java.io.BufferedReader;
  17. import java.io.File;
  18. import java.io.FileInputStream;
  19. import java.io.FileNotFoundException;
  20. import java.io.IOException;
  21. import java.io.InputStreamReader;
  22. import java.util.Date;
  23.  
  24. /** Index all text files under a directory.
  25. * <p>
  26. * This is a command-line application demonstrating simple Lucene indexing.
  27. * Run it with no command-line arguments for usage information.
  28. */
  29. public class IndexFiles {
  30.  
  31. private IndexFiles() {}
  32.  
  33. /** Index all text files under a directory. */
  34. public static void main(String[] args) {
  35.  
  36. String docsPath = "d:/"; //1. 색인 대상 문서가 있는 경로
  37. String indexPath = "d:/lucene_index/"; //2. 색인 파일이 만들어질 경로
  38.  
  39. final File docDir = new File(docsPath);
  40. if (!docDir.exists() || !docDir.canRead()) {
  41. System.out.println("Document directory '" +docDir.getAbsolutePath()+ "' does not exist or is not readable, please check the path");
  42. System.exit(1);
  43. }
  44.  
  45. Date start = new Date();
  46.  
  47. try {
  48. System.out.println("Indexing to directory '" + indexPath + "'...");
  49.  
  50. //3. 여기는 루씬에서 색인을 위한 IndexWriter를 생성하는 부분입니다.
  51. Directory dir = FSDirectory.open(new File(indexPath));
  52. Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_31); //문서 내용을 분석 할 때 사용 될 Analyzer
  53. IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_31, analyzer);
  54.  
  55. boolean create = true; //4. 색인 파일을 새로 생성 할 것인지의 여부
  56.  
  57. if (create) {
  58. // Create a new index in the directory, removing any
  59. // previously indexed documents:
  60. iwc.setOpenMode(OpenMode.CREATE); //5. 새로운 인덱스 파일을 만든다. 기존 인덱스 파일은 삭제됩니다.
  61. } else {
  62. // Add new documents to an existing index:
  63. iwc.setOpenMode(OpenMode.CREATE_OR_APPEND); //6. 원래 있던 인덱스 파일에 문서를 추가합니다.
  64. }
  65.  
  66. // Optional: for better indexing performance, if you
  67. // are indexing many documents, increase the RAM
  68. // buffer. But if you do this, increase the max heap
  69. // size to the JVM (eg add -Xmx512m or -Xmx1g):
  70. //
  71. // iwc.setRAMBufferSizeMB(256.0); //7. IndexWriterConfig가 새로 생긴 클래스입니다. 이 부분은 색인 속도 증가를 위해
  72. // 사용되는 옵션으로 보입니다.
  73.  
  74. IndexWriter writer = new IndexWriter(dir, iwc); //8. 드디어 IndexWriter를 생성합니다.
  75. indexDocs(writer, docDir); //9. 색인 대상 문서들이 있는 디렉토리에서 문서를 읽어 색인을 합니다.
  76.  
  77. // NOTE: if you want to maximize search performance,
  78. // you can optionally call optimize here. This can be
  79. // a costly operation, so generally it's only worth
  80. // it when your index is relatively static (ie you're
  81. // done adding documents to it):
  82. //
  83. // writer.optimize();
  84.  
  85. writer.close();
  86.  
  87. Date end = new Date();
  88. System.out.println(end.getTime() - start.getTime() + " total milliseconds");
  89.  
  90. } catch (IOException e) {
  91. System.out.println(" caught a " + e.getClass() +
  92. "\n with message: " + e.getMessage());
  93. }
  94. }
  95.  
  96. /**
  97. * Indexes the given file using the given writer, or if a directory is given,
  98. * recurses over files and directories found under the given directory.
  99. *
  100. * NOTE: This method indexes one document per input file. This is slow. For good
  101. * throughput, put multiple documents into your input file(s). An example of this is
  102. * in the benchmark module, which can create "line doc" files, one document per line,
  103. * using the
  104. * <a href="../../../../../contrib-benchmark/org/apache/lucene/benchmark/byTask/tasks/WriteLineDocTask.html"
  105. * >WriteLineDocTask</a>.
  106. *
  107. * @param writer Writer to the index where the given file/dir info will be stored
  108. * @param file The file to index, or the directory to recurse into to find files to index
  109. * @throws IOException
  110. */
  111. static void indexDocs(IndexWriter writer, File file)
  112. throws IOException {
  113. // do not try to index files that cannot be read
  114. if (file.canRead()) {
  115. if (file.isDirectory()) {
  116. String[] files = file.list();
  117. // an IO error could occur
  118. if (files != null) {
  119. for (int i = 0; i < files.length; i++) {
  120. if(files[i].endsWith("txt"))
  121. indexDocs(writer, new File(file, files[i])); //10. 재귀호출을 통해 파일이 디렉토리가 아닌 경우 문서를 색인 합니다.
  122. }
  123. }
  124. } else {
  125.  
  126. FileInputStream fis;
  127. try {
  128. fis = new FileInputStream(file); //11. 문서내용을 가져오기 위해 Stream을 엽니다.
  129. } catch (FileNotFoundException fnfe) {
  130. // at least on windows, some temporary files raise this exception with an "access denied" message
  131. // checking if the file can be read doesn't help
  132. return;
  133. }
  134.  
  135. try {
  136.  
  137. // make a new, empty document
  138. //12. 문서 색인의 단위입니다. 하나의 Document가 하나의 Row입니다.
  139. Document doc = new Document();
  140.  
  141. // Add the path of the file as a field named "path". Use a
  142. // field that is indexed (i.e. searchable), but don't tokenize
  143. // the field into separate words and don't index term frequency
  144. // or positional information:
  145.  
  146. //13. 문서 색인단위가 Document인데, 이 Document에는 여러개의 필드가 포함될 수 있습니다.
  147. // 이 필드를 생성합니다. 아래의 경우 path라는 필드명으로 파일의 path를 색인합니다.
  148. // 기타 옵션등에 대해서는 나중에 다시 설명을 할 예정입니다.
  149. Field pathField = new Field("path", file.getPath(), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS);
  150. pathField.setOmitTermFreqAndPositions(true);
  151. doc.add(pathField);
  152.  
  153. // Add the last modified date of the file a field named "modified".
  154. // Use a NumericField that is indexed (i.e. efficiently filterable with
  155. // NumericRangeFilter). This indexes to milli-second resolution, which
  156. // is often too fine. You could instead create a number based on
  157. // year/month/day/hour/minutes/seconds, down the resolution you require.
  158. // For example the long value 2011021714 would mean
  159. // February 17, 2011, 2-3 PM.
  160.  
  161. //14. Field에는 숫자를 색인 할 수 있는 전용 클래스도 존재합니다.
  162. // 마찬가지로 나중에 설명드리겠지만, 정렬등에서 속도에 이득이 있습니다.
  163. NumericField modifiedField = new NumericField("modified");
  164. modifiedField.setLongValue(file.lastModified());
  165. doc.add(modifiedField);
  166.  
  167. // Add the contents of the file to a field named "contents". Specify a Reader,
  168. // so that the text of the file is tokenized and indexed, but not stored.
  169. // Note that FileReader expects the file to be in UTF-8 encoding.
  170. // If that's not the case searching for special characters will fail.
  171.  
  172. //15. path, modified, 그리고 아래의 contents라는 이름의 필드를 Document에 추가합니다.
  173. // 마찬가지로 나중에 다시 말씀드리겠지만, 이 예제에서는 필드에 String, Numeric, Reader등 여러 타입의
  174. // 내용을 추가 할 수 있다는 것을 보여줍니다.
  175. doc.add(new Field("contents", new BufferedReader(new InputStreamReader(fis, "UTF-8"))));
  176.  
  177. if (writer.getConfig().getOpenMode() == OpenMode.CREATE) { //16. 인덱스 파일을 새로 생성하도록 되어 있는 옵션이면 add...
  178. // New index, so we just add the document (no old document can be there):
  179. System.out.println("adding " + file);
  180. writer.addDocument(doc);
  181. } else {
  182. // Existing index (an old copy of this document may have been indexed) so
  183. // we use updateDocument instead to replace the old one matching the exact
  184. // path, if present:
  185. System.out.println("updating " + file); //17. Create or Update라면 update를 합니다.
  186. // 이문호님께서 알려주셨습니다.
  187. // updateDocument는 2.x 부터 생긴 메서드입니다. 그 이전버전에서는 update는 delete -> insert 메서드를 사용해서
  188. // 구현해야 합니다.
  189. writer.updateDocument(new Term("path", file.getPath()), doc);
  190. }
  191.  
  192. } finally {
  193. fis.close();
  194. }
  195. }
  196. }
  197. }
  198. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement