1460
|
1 package goodjava.lucene.api;
|
|
2
|
|
3 import java.io.IOException;
|
|
4 import java.util.Map;
|
|
5 import java.util.HashMap;
|
|
6 import java.util.List;
|
|
7 import org.apache.lucene.analysis.Analyzer;
|
|
8 import org.apache.lucene.document.Document;
|
|
9 import org.apache.lucene.document.Field;
|
|
10 import org.apache.lucene.document.StoredField;
|
|
11 import org.apache.lucene.document.StringField;
|
|
12 import org.apache.lucene.document.TextField;
|
|
13 import org.apache.lucene.document.IntField;
|
|
14 import org.apache.lucene.document.LongField;
|
|
15 import org.apache.lucene.document.DoubleField;
|
|
16 import org.apache.lucene.document.FloatField;
|
|
17 import org.apache.lucene.index.IndexWriter;
|
|
18 import org.apache.lucene.index.IndexWriterConfig;
|
|
19 import org.apache.lucene.index.Term;
|
|
20 import org.apache.lucene.index.DirectoryReader;
|
|
21 import org.apache.lucene.index.IndexReader;
|
|
22 import org.apache.lucene.search.Query;
|
|
23 import org.apache.lucene.search.IndexSearcher;
|
|
24 import org.apache.lucene.store.Directory;
|
|
25 import org.apache.lucene.util.Version;
|
|
26
|
|
27
|
|
28 public final class LuceneIndexWriter implements GoodIndexWriter {
|
|
29 final FieldAnalyzer fieldAnalyzer = new FieldAnalyzer();
|
|
30 public final IndexWriterConfig luceneConfig;
|
|
31 public final GoodIndexWriterConfig goodConfig;
|
|
32 public final IndexWriter luceneWriter;
|
|
33 private final Map<String,Boolean> indexedMap = new HashMap<String,Boolean>();
|
|
34
|
|
35 public LuceneIndexWriter(Version matchVersion,Directory dir,GoodIndexWriterConfig goodConfig) throws IOException {
|
|
36 luceneConfig = new IndexWriterConfig(matchVersion,fieldAnalyzer);
|
|
37 luceneWriter = new IndexWriter(dir,luceneConfig);
|
|
38 this.goodConfig = goodConfig;
|
|
39 }
|
|
40
|
|
41 public void close() throws IOException {
|
|
42 luceneWriter.close();
|
|
43 }
|
|
44
|
|
45 public void commit() throws IOException {
|
|
46 luceneWriter.commit();
|
|
47 }
|
|
48
|
|
49 public void rollback() throws IOException {
|
|
50 luceneWriter.rollback();
|
|
51 }
|
|
52
|
|
53 public void deleteAll() throws IOException {
|
|
54 luceneWriter.deleteAll();
|
|
55 }
|
|
56
|
|
57 public void deleteDocuments(Query query) throws IOException {
|
|
58 luceneWriter.deleteDocuments(query);
|
|
59 }
|
|
60
|
|
61 public void addDocument(Map<String,Object> storedFields) throws IOException {
|
|
62 Document doc = newDocument(storedFields);
|
|
63 luceneWriter.addDocument(doc);
|
|
64 }
|
|
65
|
|
66 public void updateDocument(String keyFieldName,Map<String,Object> storedFields) throws IOException {
|
|
67 if( !isIndexed(keyFieldName) )
|
|
68 throw new RuntimeException("can't update using unindexed field "+keyFieldName);
|
|
69 if( fieldAnalyzer.isAdded(keyFieldName) )
|
|
70 throw new RuntimeException("can't update using analyzeed field "+keyFieldName);
|
|
71 Document doc = newDocument(storedFields);
|
|
72 Object keyValue = storedFields.get(keyFieldName);
|
|
73 if( keyValue==null )
|
|
74 throw new RuntimeException("no value for field "+keyFieldName);
|
|
75 Term term = LuceneUtils.term(keyFieldName,keyValue);
|
|
76 luceneWriter.updateDocument(term,doc);
|
|
77 }
|
|
78
|
|
79 private Document newDocument(Map<String,Object> storedFields) {
|
|
80 Document doc = new Document();
|
|
81 addFields(doc,storedFields,Field.Store.YES);
|
|
82 Map<String,Object> unstoredFields = goodConfig.getUnstoredFields(storedFields);
|
|
83 addFields(doc,unstoredFields,Field.Store.NO);
|
|
84 return doc;
|
|
85 }
|
|
86
|
|
87 private void addFields( Document doc, Map<String,Object> fields, Field.Store store ) {
|
|
88 for( Map.Entry<String,Object> entry : fields.entrySet() ) {
|
|
89 String name = entry.getKey();
|
|
90 Object value = entry.getValue();
|
|
91 if( value instanceof List ) {
|
|
92 for( Object v : (List)value ) {
|
|
93 doc.add( newField(name,v,store) );
|
|
94 }
|
|
95 } else {
|
|
96 doc.add( newField(name,value,store) );
|
|
97 }
|
|
98 }
|
|
99 }
|
|
100
|
|
101 private Field newField( String name, Object value, Field.Store store ) {
|
|
102 boolean isIndexed = isIndexed(name);
|
|
103 if( store==Field.Store.NO && !isIndexed )
|
|
104 throw new RuntimeException("field '"+name+"' is unstored and unindexed");
|
|
105 if( value instanceof String ) {
|
|
106 String s = (String)value;
|
|
107 if( !isIndexed ) {
|
|
108 return new StoredField(name,s);
|
|
109 } else if( !fieldAnalyzer.isAdded(name) ) {
|
|
110 return new StringField(name,s,store);
|
|
111 } else {
|
|
112 return new TextField(name,s,store);
|
|
113 }
|
|
114 } else if( value instanceof Integer ) {
|
|
115 int i = (Integer)value;
|
|
116 if( !isIndexed ) {
|
|
117 return new StoredField(name,i);
|
|
118 } else {
|
|
119 return new IntField(name,i,store);
|
|
120 }
|
|
121 } else if( value instanceof Long ) {
|
|
122 long i = (Long)value;
|
|
123 if( !isIndexed ) {
|
|
124 return new StoredField(name,i);
|
|
125 } else {
|
|
126 return new LongField(name,i,store);
|
|
127 }
|
|
128 } else if( value instanceof Double ) {
|
|
129 double i = (Double)value;
|
|
130 if( !isIndexed ) {
|
|
131 return new StoredField(name,i);
|
|
132 } else {
|
|
133 return new DoubleField(name,i,store);
|
|
134 }
|
|
135 } else if( value instanceof Float ) {
|
|
136 float i = (Float)value;
|
|
137 if( !isIndexed ) {
|
|
138 return new StoredField(name,i);
|
|
139 } else {
|
|
140 return new FloatField(name,i,store);
|
|
141 }
|
|
142 } else if( value instanceof byte[] ) {
|
|
143 if( isIndexed )
|
|
144 throw new RuntimeException("can't index byte field "+name);
|
|
145 byte[] b = (byte[])value;
|
|
146 return new StoredField(name, b);
|
|
147 } else
|
|
148 throw new RuntimeException("invalid value type "+value.getClass()+"' for field '"+name+"'");
|
|
149 }
|
|
150
|
|
151 private synchronized boolean isIndexed(String fieldName) {
|
|
152 Boolean b = indexedMap.get(fieldName);
|
|
153 if( b==null ) {
|
|
154 b = goodConfig.isIndexed(fieldName);
|
|
155 indexedMap.put(fieldName,b);
|
|
156 Analyzer analyzer = goodConfig.getAnalyzer(fieldName);
|
|
157 if( analyzer!=null )
|
|
158 fieldAnalyzer.add(fieldName,analyzer);
|
|
159 }
|
|
160 return b;
|
|
161 }
|
|
162
|
|
163
|
|
164 public void reindexDocuments(final String keyFieldName,Query query) throws IOException {
|
|
165 IndexReader reader = DirectoryReader.open(luceneWriter.getDirectory());
|
|
166 final IndexSearcher searcher = new IndexSearcher(reader);
|
|
167 searcher.search( query, new GoodCollector(){
|
|
168 public void collectDoc(int iDoc) throws IOException {
|
|
169 Document doc = searcher.doc(iDoc);
|
|
170 Map<String,Object> storedFields = LuceneUtils.toMap(doc);
|
|
171 updateDocument(keyFieldName,storedFields);
|
|
172 }
|
|
173 });
|
|
174 reader.close();
|
|
175 }
|
|
176 }
|