27
27
public class Indexer {
29
29
private static Map<File, IndexWriter> indexs = new HashMap<File, IndexWriter>();
30
31
private static Map<File, IndexSearcher> searchers = new HashMap<File, IndexSearcher>();
31
33
private static Map<File, Long> writerStats = new HashMap<File, Long>();
32
35
private static long OPTIMIZE_THRESHOLD;
33
37
private static String ANALYSER_CLASS;
36
OPTIMIZE_THRESHOLD = Long.parseLong(System.getProperty("zdb.optimize","1000"));
37
ANALYSER_CLASS = System.getProperty("zdb.analyser.class","org.apache.lucene.analysis.standard.StandardAnalyzer");
40
private static Analyzer getAnalyser () {
42
Class clazz = Class.forName(ANALYSER_CLASS);
43
return (Analyzer) clazz.newInstance();
44
} catch (Exception e) {
45
throw new RuntimeException(e);
41
OPTIMIZE_THRESHOLD = Long.parseLong(System.getProperty("zdb.optimize", "1000"));
42
ANALYSER_CLASS = System.getProperty("zdb.analyser.class", "org.apache.lucene.analysis.standard.StandardAnalyzer");
45
private static Analyzer getAnalyser() {
47
Class clazz = Class.forName(ANALYSER_CLASS);
48
return (Analyzer) clazz.newInstance();
49
} catch (Exception e) {
50
throw new RuntimeException(e);
49
53
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Indexs management
50
54
private static IndexWriter getIndexWriterForBucket(File bucket) {
68
72
IndexWriter wr = indexs.get(bucket);
69
73
long count = getStat(bucket).longValue();
70
if( count > OPTIMIZE_THRESHOLD) {
71
long start = System.currentTimeMillis();
73
writerStats.put(bucket, new Long (0));
74
System.out.println("Optimized index "+bucket.getName()+" in "+(System.currentTimeMillis()-start)+" ms");
74
if (count > OPTIMIZE_THRESHOLD) {
75
long start = System.currentTimeMillis();
77
writerStats.put(bucket, new Long(0));
78
System.out.println("Optimized index " + bucket.getName() + " in " + (System.currentTimeMillis() - start) + " ms");
77
81
} catch (Exception e) {
78
82
throw new UnexpectedException("Cannot open index", e);
82
private static Long getStat (File file) {
83
if (!writerStats.containsKey(file))
84
writerStats.put(file, new Long (0));
85
return writerStats.get(file);
86
private static Long getStat(File file) {
87
if (!writerStats.containsKey(file)) {
88
writerStats.put(file, new Long(0));
90
return writerStats.get(file);
88
93
private static IndexSearcher getIndexSearcherForBucket(File bucket, boolean forceRefresh) {
90
95
if (!searchers.containsKey(bucket) || forceRefresh) {
91
96
synchronized (Indexer.class) {
92
IndexSearcher old = searchers.get(bucket);
97
IndexSearcher old = searchers.get(bucket);
93
98
File indexRoot = new File(bucket, "_index");
94
99
if (indexRoot.exists()) {
95
100
IndexSearcher indexSearcher = new IndexSearcher(FSDirectory.getDirectory(indexRoot));
96
101
searchers.put(bucket, indexSearcher);
114
119
String value = indexString.substring(i + 1);
115
120
String[] parts = declaration.split(";");
116
121
String key = parts[parts.length - 1];
117
zdb.client.Document.Index index = new zdb.client.Document.Index(key,value);
122
zdb.client.Document.Index index = new zdb.client.Document.Index(key, value);
118
123
for (String part : parts) {
119
124
if (part.equals("STORED")) {
120
125
index.stored = true;
136
140
public static Document toDocument(String id, List<String> indexes) {
137
141
Document luceneDoc = new Document();
138
142
luceneDoc.add(new Field("_docID", id, Field.Store.YES, Field.Index.UN_TOKENIZED));
140
144
for (String indexInfos : indexes) {
141
145
Index newindex = parseIndex(indexInfos);
142
146
Field.Index luceneIndex = Field.Index.UN_TOKENIZED;
143
if( ! newindex.indexed )
144
luceneDoc.add(new Field( newindex.name, newindex.value.toString(), Field.Store.NO, Field.Index.NO ));
145
else if( newindex.fulltext )
146
luceneDoc.add(new Field( newindex.name, newindex.value.toString(), Field.Store.YES, Field.Index.TOKENIZED ));
148
luceneDoc.add(new Field( newindex.name, newindex.value.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED ));
147
if (!newindex.indexed) {
148
luceneDoc.add(new Field(newindex.name, newindex.value.toString(), Field.Store.NO, Field.Index.NO));
149
} else if (newindex.fulltext) {
150
luceneDoc.add(new Field(newindex.name, newindex.value.toString(), Field.Store.YES, Field.Index.TOKENIZED));
152
luceneDoc.add(new Field(newindex.name, newindex.value.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
149
153
// Field.Index == (Boolean) pi[2] ? ((Boolean) pi[3] ? Field.Index.TOKENIZED : Field.Index.UN_TOKENIZED) : Field.Index.NO;
151
156
return luceneDoc;
154
159
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ API
155
public static void storeToIndex(File bucket, String id, Document document) throws Exception {
160
public static void storeToIndex(File bucket, String id, Document document) throws
156
162
IndexWriter indexWriter = getIndexWriterForBucket(bucket);
157
163
indexWriter.deleteDocuments(new Term("_docID", id));
158
164
indexWriter.addDocument(document);
162
168
writerStats.put(bucket, new Long(opCount));
163
169
getIndexSearcherForBucket(bucket, true);
166
public static void deleteFromIndex (File bucket, String id) throws Exception {
172
public static void deleteFromIndex(File bucket, String id) throws Exception {
167
173
IndexWriter indexWriter = getIndexWriterForBucket(bucket);
168
174
indexWriter.deleteDocuments(new Term("_docID", id));
169
175
indexWriter.flush();
170
176
getIndexSearcherForBucket(bucket, true);
173
public static void initialize (File bucket) {
174
getIndexWriterForBucket(bucket);
179
public static void initialize(File bucket) {
180
getIndexWriterForBucket(bucket);
177
public static Document searchOne (File bucket, Query query) {
183
public static Document searchOne(File bucket, Query query) {
179
185
IndexSearcher searcher = getIndexSearcherForBucket(bucket, false);
180
186
if (searcher != null) {
181
Hits hits = searcher.search(query);
182
Hit hit = (Hit)hits.iterator().next();
187
Hits hits = searcher.search(query);
188
Hit hit = (Hit) hits.iterator().next();
183
189
return hit.getDocument();
187
193
throw new UnexpectedException("IO error", e);
191
197
public static Hits search(File bucket, Query query, Sort sort) {
193
199
IndexSearcher searcher = getIndexSearcherForBucket(bucket, false);
194
Collection<String> fields = ( Collection<String>)searcher.getIndexReader().getFieldNames(FieldOption.ALL);
200
Collection<String> fields = (Collection<String>) searcher.getIndexReader().getFieldNames(FieldOption.ALL);
195
201
SortField[] sorts = sort.getSort();
196
202
for (SortField sortField : sorts) {
197
if (!fields.contains(sort))
198
return searcher.search(query, null, new Sort(new String[0]));
203
if (!fields.contains(sort)) {
204
return searcher.search(query, null, new Sort(new String[0]));
200
207
if (searcher != null) {
201
208
return searcher.search(query, null, sort);