#include "LCIndexSearcher.h" #include "LCFieldSortedHitQueue.h" #include "LCHitQueue.h" #include "LCFilter.h" #include "LCScoreDoc.h" #include "LCTopFieldDocs.h" #include "LCQuery.h" #include "LCSort.h" #include "LCBitVector.h" #include "LCIndexReader.h" #include "LCTerm.h" #include "LCDocument.h" #include "LCTopDocCollector.h" #include "LCTopFieldDocCollector.h" #include "GNUstep.h" #include "float.h" /** Implements search over a single IndexReader. * *

Applications usually need only call the inherited {@link #search(Query)} * or {@link #search(Query,Filter)} methods. For performance reasons it is * recommended to open only one IndexSearcher and use it for all of your searches. */ @interface LCHitCollector3: LCHitCollector { LCBitVector *bits; LCHitCollector *collector; } - (id) initWithReader: (LCIndexReader *) reader filter: (LCFilter *) filter hitCollector: (LCHitCollector *) collector; @end @implementation LCHitCollector3 - (id) initWithReader: (LCIndexReader *) reader filter: (LCFilter *) filter hitCollector: (LCHitCollector *) hc { self = [self init]; bits = [filter bits: reader]; ASSIGN(collector, hc); return self; } - (void) collect: (int) doc score: (float) score { if ([bits bit: doc]) // skip docs not in bits { [collector collect: doc score: score]; } } - (void) dealloc { DESTROY(collector); [super dealloc]; } @end @interface LCIndexSearcher (LCPrivate) - (id) initWithReader: (LCIndexReader *) indexReader close: (BOOL) closeReader; @end @implementation LCIndexSearcher /** Creates a searcher searching the index in the named directory. */ - (id) initWithPath: (NSString *) path { return [self initWithReader: [LCIndexReader openPath: path] close: YES]; } /** Creates a searcher searching the index in the provided directory. */ - (id) initWithDirectory: (id ) directory { return [self initWithReader: [LCIndexReader openDirectory: directory] close: YES]; } /** Creates a searcher searching the provided index. */ - (id) initWithReader: (LCIndexReader *) indexReader { return [self initWithReader: indexReader close: NO]; } - (id) initWithReader: (LCIndexReader *) indexReader close: (BOOL) close { self = [self init]; ASSIGN(reader, indexReader); closeReader = close; return self; } /** Return the {@link IndexReader} this searches. */ - (LCIndexReader *) indexReader { return reader; } /** * Note that the underlying IndexReader is not closed, if * IndexSearcher was constructed with IndexSearcher(IndexReader r). * If the IndexReader was supplied implicitly by specifying a directory, then * the IndexReader gets closed. */ - (void) close { if(closeReader) [reader close]; } - (int) documentFrequencyWithTerm: (LCTerm *) term { return [reader documentFrequency: term]; } - (LCDocument *) document: (int) i { return [reader document: i]; } - (int) maximalDocument { return [reader maximalDocument]; } - (LCTopDocs *) search: (id ) weight filter: (LCFilter *) filter maximum: (int) nDocs { if (nDocs <= 0) // null might be returned from hq.top() below. { NSLog(@"nDocs must be > 0 "); return nil; } LCTopDocCollector *collector = [[LCTopDocCollector alloc] initWithMaximalHits: nDocs]; [self search: weight filter: filter hitCollector: collector]; AUTORELEASE(collector); return [collector topDocs]; } - (LCTopFieldDocs *) search: (id ) weight filter: (LCFilter *) filter maximum: (int) nDocs sort: (LCSort *) sort { LCTopFieldDocCollector *collector = [[LCTopFieldDocCollector alloc] initWithReader: reader sort: sort maximalHits: nDocs]; [self search: weight filter: filter hitCollector: collector]; AUTORELEASE(collector); return (LCTopFieldDocs *)[collector topDocs]; } - (void) search: (id ) weight filter: (LCFilter *) filter hitCollector: (LCHitCollector *) results { LCHitCollector *collector = results; if (filter != nil) { collector = [[LCHitCollector3 alloc] initWithReader: reader filter: filter hitCollector: results]; AUTORELEASE(collector); } LCScorer *scorer = [weight scorer: reader]; if (scorer == nil) return; [scorer score: collector]; } - (LCQuery *) rewrite: (LCQuery *) original { LCQuery *query = original; LCQuery *rewrittenQuery; for (rewrittenQuery = [query rewrite: reader]; rewrittenQuery != query; rewrittenQuery = [query rewrite: reader]) { query = rewrittenQuery; } return query; } - (LCExplanation *) explain: (id ) weight document: (int) doc { return [weight explain: reader document: doc]; } @end