Lucene 4.7 學習及實例demo


  很早就聽說Lucene的大名了,但一直沒空研究,今天抽了一個下午時間,學習了一下Lucene,寫了一個簡單的Demo,總的感受是使用起來簡單方便,在使用之前,首先要理解以下關鍵的類:

Document 
Document 是用來描述文檔的,這里的文檔可以指一個 HTML 頁面,一封電子郵件,或者是一個文本文件。一個 Document 對象由多個 Field 對象組成的。可以把一個 Document 對象想象成數據庫中的一個記錄,而每個 Field 對象就是記錄的一個字段。 

Field 
Field 對象是用來描述一個文檔的某個屬性的,比如一封電子郵件的標題和內容可以用兩個 Field 對象分別描述。 

Analyzer 
在一個文檔被索引之前,首先需要對文檔內容進行分詞處理,這部分工作就是由 Analyzer 來做的。Analyzer 類是一個抽象類,它有多個實現。針對不同的語言和應用需要選擇適合的 Analyzer。Analyzer 把分詞后的內容交給 IndexWriter 來建立索引。 

IndexWriter 
IndexWriter 是 Lucene 用來創建索引的一個核心的類,他的作用是把一個個的 Document 對象加到索引中來。 

Directory 
這個類代表了 Lucene 的索引的存儲的位置,這是一個抽象類,它目前有兩個實現,第一個是 FSDirectory,它表示一個存儲在文件系統中的索引的位置。第二個是 RAMDirectory,它表示一個存儲在內存當中的索引的位置。 

Query 
這是一個抽象類,他有多個實現,比如 TermQuery, BooleanQuery, PrefixQuery. 這個類的目的是把用戶輸入的查詢字符串封裝成 Lucene 能夠識別的 Query。 

IndexSearcher 
IndexSearcher 是用來在建立好的索引上進行搜索的。它只能以只讀的方式打開一個索引,所以可以有多個 IndexSearcher 的實例在一個索引上進行操作。

Hits 
Hits 是用來保存搜索結果的。 

 

理解了這些類之后,我寫了一個簡單的demo,包括索引構建和索引搜索,以后如果要做復雜的搜索,可以根據這個demo做擴展,是不是很簡單哈。

  1 import java.io.File;
  2 import java.io.IOException;
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 import org.apache.lucene.analysis.Analyzer;
  6 import org.apache.lucene.analysis.standard.StandardAnalyzer;
  7 import org.apache.lucene.document.Document;
  8 import org.apache.lucene.document.Field;
  9 import org.apache.lucene.document.TextField;
 10 import org.apache.lucene.index.DirectoryReader;
 11 import org.apache.lucene.index.IndexWriter;
 12 import org.apache.lucene.index.IndexWriterConfig;
 13 import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
 14 import org.apache.lucene.search.IndexSearcher;
 15 import org.apache.lucene.search.Query;
 16 import org.apache.lucene.search.ScoreDoc;
 17 import org.apache.lucene.store.Directory;
 18 import org.apache.lucene.store.FSDirectory;
 19 import org.apache.lucene.util.Version;
 20 
 21 /**
 22  * Lucene Demo
 23  * Author: herui
 24  * DateTime: 2014-3-31 下午3:39:54
 25  */
 26 public class LuceneDemo {
 27     
 28     /**
 29      * 根據內容,構建索引
 30      * @param analyzer
 31      * @param directory
 32      * @param items
 33      * @return
 34      */
 35     private boolean buildIndexer(Analyzer analyzer, Directory directory, List<Item> items) {
 36         IndexWriter iwriter = null;
 37         try {
 38             // 配置索引
 39             iwriter = new IndexWriter(directory, new IndexWriterConfig(
 40                     Version.LUCENE_47, analyzer));
 41             // 刪除所有document
 42             iwriter.deleteAll();
 43             // 將文檔信息存入索引
 44             Document doc[] = new Document[items.size()];
 45             for (int i = 0; i < items.size(); i++) {
 46                 doc[i] = new Document();
 47                 
 48                 Item item = items.get(i);
 49                 java.lang.reflect.Field[] fields = item.getClass().getDeclaredFields();
 50                 for (java.lang.reflect.Field field : fields) {
 51                     String fieldName = field.getName();
 52                     String getMethodName = "get"+toFirstLetterUpperCase(fieldName);
 53                     Object obj = item.getClass().getMethod(getMethodName).invoke(item);
 54                     doc[i].add(new Field(fieldName, (String)obj, TextField.TYPE_STORED));
 55                 }
 56                 
 57                 iwriter.addDocument(doc[i]);
 58             }
 59         } catch (Exception e) {
 60             e.printStackTrace();
 61             return false;
 62         } finally {
 63             try {
 64                 iwriter.close();
 65             } catch (IOException e) {
 66             }
 67         }
 68         return true;
 69     }
 70     
 71     /**
 72      * 根據keyword搜索索引
 73      * @param analyzer
 74      * @param directory
 75      * @param keyword
 76      * @return
 77      */
 78     public List<Item> searchIndexer(Analyzer analyzer, Directory directory, String keyword) {
 79         DirectoryReader ireader = null;
 80         List<Item> result = new ArrayList<Item>();
 81         try {
 82             // 設定搜索目錄
 83             ireader = DirectoryReader.open(directory);
 84             IndexSearcher isearcher = new IndexSearcher(ireader);
 85 
 86             // 對多field進行搜索
 87             java.lang.reflect.Field[] fields = Item.class.getDeclaredFields();
 88             int length = fields.length;
 89             String[] multiFields = new String[length];
 90             for (int i = 0; i < length; i++) {
 91                 multiFields[i] = fields[i].getName();
 92             }
 93             MultiFieldQueryParser parser = new MultiFieldQueryParser(
 94                     Version.LUCENE_47, multiFields, analyzer);
 95 
 96             // 設定具體的搜索詞
 97             Query query = parser.parse(keyword);
 98             ScoreDoc[] hits = isearcher.search(query, null, 10).scoreDocs;
 99 
100             for (int i = 0; i < hits.length; i++) {
101                 Document hitDoc = isearcher.doc(hits[i].doc);
102                 Item item = new Item();
103                 for (String field : multiFields) {
104                     String setMethodName = "set"+toFirstLetterUpperCase(field);
105                     item.getClass().getMethod(setMethodName, String.class).invoke(item, hitDoc.get(field));
106                 }
107                 result.add(item);
108             }
109         } catch (Exception e) {
110             e.printStackTrace();
111             return null;
112         } finally {
113             try {
114                 ireader.close();
115                 directory.close();
116             } catch (IOException e) {
117             }
118         }
119         return result;
120     }
121     
122     /**
123      * 首字母轉大寫
124      * @param str
125      * @return
126      */
127     public static String toFirstLetterUpperCase(String str) {  
128         if(str == null || str.length() < 2){  
129             return str;  
130         }  
131         return str.substring(0, 1).toUpperCase() + str.substring(1, str.length());  
132      }  
133     
134     public static void main(String[] args) throws Exception {
135         LuceneDemo demo = new LuceneDemo();
136         Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_47);
137         
138         List<Item> items = new ArrayList<Item>();
139         items.add(new Item("1", "first", "This is the text to be greatly indexed."));
140         items.add(new Item("2", "second", "This is great"));
141         items.add(new Item("3", "third", "I love apple and pear. "));
142         items.add(new Item("4", "four", "我是中國人"));
143         items.add(new Item("5", "five", "我叫何瑞"));
144         
145         // 索引存到內存中的目錄
146         //Directory directory = new RAMDirectory();
147         // 索引存儲到硬盤
148         File file = new File("d:/lucene");
149         Directory directory = FSDirectory.open(file);
150         demo.buildIndexer(analyzer, directory, items);
151         List<Item> result = demo.searchIndexer(analyzer, directory, "中國");
152         
153         for (Item item : result) {
154             System.out.println(item.toString());
155         }
156     }
157 }

Item.java

 1 public class Item {
 2     
 3     private String id;
 4     private String title;
 5     private String content;
 6     
 7     public Item() {
 8     }
 9     
10     public Item(String id, String title, String content) {
11         this.id = id;
12         this.title = title;
13         this.content = content;
14     }
15     
16     public String getId() {
17         return id;
18     }
19     public void setId(String id) {
20         this.id = id;
21     }
22     public String getTitle() {
23         return title;
24     }
25     public void setTitle(String title) {
26         this.title = title;
27     }
28     public String getContent() {
29         return content;
30     }
31     public void setContent(String content) {
32         this.content = content;
33     }
34     
35     public String toString() {
36         StringBuilder sb = new StringBuilder();
37         sb.append("[id=").append(id).append(",title=").append(title)
38             .append(",content=").append(content).append("]");
39         return sb.toString();
40     }
41 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM