use of org.apache.lucene.search.TopFieldCollector in project lucene-solr by apache.
the class AnalyzingInfixSuggester method lookup.
/**
* This is an advanced method providing the capability to send down to the suggester any
* arbitrary lucene query to be used to filter the result of the suggester
*
* @param key the keyword being looked for
* @param contextQuery an arbitrary Lucene query to be used to filter the result of the suggester. {@link #addContextToQuery} could be used to build this contextQuery.
* @param num number of items to return
* @param allTermsRequired all searched terms must match or not
* @param doHighlight if true, the matching term will be highlighted in the search result
* @return the result of the suggester
* @throws IOException f the is IO exception while reading data from the index
*/
public List<LookupResult> lookup(CharSequence key, BooleanQuery contextQuery, int num, boolean allTermsRequired, boolean doHighlight) throws IOException {
if (searcherMgr == null) {
throw new IllegalStateException("suggester was not built");
}
final BooleanClause.Occur occur;
if (allTermsRequired) {
occur = BooleanClause.Occur.MUST;
} else {
occur = BooleanClause.Occur.SHOULD;
}
BooleanQuery.Builder query;
Set<String> matchedTokens;
String prefixToken = null;
try (TokenStream ts = queryAnalyzer.tokenStream("", new StringReader(key.toString()))) {
//long t0 = System.currentTimeMillis();
ts.reset();
final CharTermAttribute termAtt = ts.addAttribute(CharTermAttribute.class);
final OffsetAttribute offsetAtt = ts.addAttribute(OffsetAttribute.class);
String lastToken = null;
query = new BooleanQuery.Builder();
int maxEndOffset = -1;
matchedTokens = new HashSet<>();
while (ts.incrementToken()) {
if (lastToken != null) {
matchedTokens.add(lastToken);
query.add(new TermQuery(new Term(TEXT_FIELD_NAME, lastToken)), occur);
}
lastToken = termAtt.toString();
if (lastToken != null) {
maxEndOffset = Math.max(maxEndOffset, offsetAtt.endOffset());
}
}
ts.end();
if (lastToken != null) {
Query lastQuery;
if (maxEndOffset == offsetAtt.endOffset()) {
// Use PrefixQuery (or the ngram equivalent) when
// there was no trailing discarded chars in the
// string (e.g. whitespace), so that if query does
// not end with a space we show prefix matches for
// that token:
lastQuery = getLastTokenQuery(lastToken);
prefixToken = lastToken;
} else {
// Use TermQuery for an exact match if there were
// trailing discarded chars (e.g. whitespace), so
// that if query ends with a space we only show
// exact matches for that term:
matchedTokens.add(lastToken);
lastQuery = new TermQuery(new Term(TEXT_FIELD_NAME, lastToken));
}
if (lastQuery != null) {
query.add(lastQuery, occur);
}
}
if (contextQuery != null) {
boolean allMustNot = true;
for (BooleanClause clause : contextQuery.clauses()) {
if (clause.getOccur() != BooleanClause.Occur.MUST_NOT) {
allMustNot = false;
break;
}
}
if (allMustNot) {
// All are MUST_NOT: add the contextQuery to the main query instead (not as sub-query)
for (BooleanClause clause : contextQuery.clauses()) {
query.add(clause);
}
} else if (allTermsRequired == false) {
// We must carefully upgrade the query clauses to MUST:
BooleanQuery.Builder newQuery = new BooleanQuery.Builder();
newQuery.add(query.build(), BooleanClause.Occur.MUST);
newQuery.add(contextQuery, BooleanClause.Occur.MUST);
query = newQuery;
} else {
// Add contextQuery as sub-query
query.add(contextQuery, BooleanClause.Occur.MUST);
}
}
}
// TODO: we could allow blended sort here, combining
// weight w/ score. Now we ignore score and sort only
// by weight:
Query finalQuery = finishQuery(query, allTermsRequired);
//System.out.println("finalQuery=" + finalQuery);
// Sort by weight, descending:
TopFieldCollector c = TopFieldCollector.create(SORT, num, true, false, false);
// We sorted postings by weight during indexing, so we
// only retrieve the first num hits now:
Collector c2 = new EarlyTerminatingSortingCollector(c, SORT, num);
List<LookupResult> results = null;
SearcherManager mgr;
IndexSearcher searcher;
synchronized (searcherMgrLock) {
// acquire & release on same SearcherManager, via local reference
mgr = searcherMgr;
searcher = mgr.acquire();
}
try {
//System.out.println("got searcher=" + searcher);
searcher.search(finalQuery, c2);
TopFieldDocs hits = c.topDocs();
// Slower way if postings are not pre-sorted by weight:
// hits = searcher.search(query, null, num, SORT);
results = createResults(searcher, hits, num, key, doHighlight, matchedTokens, prefixToken);
} finally {
mgr.release(searcher);
}
return results;
}
use of org.apache.lucene.search.TopFieldCollector in project graphdb by neo4j-attic.
the class TopDocsIterator method toTopDocs.
private TopDocs toTopDocs(Query query, QueryContext context, Searcher searcher) throws IOException {
Sort sorting = context != null ? context.getSorting() : null;
TopDocs topDocs = null;
if (sorting == null) {
topDocs = searcher.search(query, context.getTop());
} else {
boolean forceScore = context == null || !context.getTradeCorrectnessForSpeed();
if (forceScore) {
TopFieldCollector collector = LuceneDataSource.scoringCollector(sorting, context.getTop());
searcher.search(query, collector);
topDocs = collector.topDocs();
} else {
topDocs = searcher.search(query, null, context.getTop(), sorting);
}
}
return topDocs;
}
use of org.apache.lucene.search.TopFieldCollector in project graphdb by neo4j-attic.
the class HitDoc method getMoreDocs.
/**
* Tries to add new documents to hitDocs.
* Ensures that the hit numbered <code>min</code> has been retrieved.
*/
private final void getMoreDocs(int min) throws IOException {
if (hitDocs.size() > min) {
min = hitDocs.size();
}
// double # retrieved
int n = min * 2;
// TopDocs topDocs = (sort == null) ? searcher.search(weight, filter, n) : searcher.search(weight, filter, n, sort);
TopDocs topDocs = null;
if (sort == null) {
topDocs = searcher.search(weight, filter, n);
} else {
if (this.score) {
TopFieldCollector collector = LuceneDataSource.scoringCollector(sort, n);
searcher.search(weight, null, collector);
topDocs = collector.topDocs();
} else {
topDocs = searcher.search(weight, filter, n, sort);
}
}
length = topDocs.totalHits;
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
float scoreNorm = 1.0f;
if (length > 0 && topDocs.getMaxScore() > 1.0f) {
scoreNorm = 1.0f / topDocs.getMaxScore();
}
int start = hitDocs.size() - nDeletedHits;
// any new deletions?
int nDels2 = countDeletions(searcher);
debugCheckedForDeletions = false;
if (nDeletions < 0 || nDels2 > nDeletions) {
// either we cannot count deletions, or some "previously valid hits" might have been deleted, so find exact start point
nDeletedHits = 0;
debugCheckedForDeletions = true;
int i2 = 0;
for (int i1 = 0; i1 < hitDocs.size() && i2 < scoreDocs.length; i1++) {
int id1 = ((HitDoc) hitDocs.get(i1)).id;
int id2 = scoreDocs[i2].doc;
if (id1 == id2) {
i2++;
} else {
nDeletedHits++;
}
}
start = i2;
}
int end = scoreDocs.length < length ? scoreDocs.length : length;
length += nDeletedHits;
for (int i = start; i < end; i++) {
hitDocs.addElement(new HitDoc(scoreDocs[i].score * scoreNorm, scoreDocs[i].doc));
}
nDeletions = nDels2;
}
use of org.apache.lucene.search.TopFieldCollector in project neo4j-mobile-android by neo4j-contrib.
the class TopDocsIterator method toTopDocs.
private TopDocs toTopDocs(Query query, QueryContext context, IndexSearcher searcher) throws IOException {
Sort sorting = context != null ? context.getSorting() : null;
TopDocs topDocs = null;
if (sorting == null) {
topDocs = searcher.search(query, context.getTop());
} else {
boolean forceScore = context == null || !context.getTradeCorrectnessForSpeed();
if (forceScore) {
TopFieldCollector collector = LuceneDataSource.scoringCollector(sorting, context.getTop());
searcher.search(query, collector);
topDocs = collector.topDocs();
} else {
topDocs = searcher.search(query, null, context.getTop(), sorting);
}
}
return topDocs;
}
use of org.apache.lucene.search.TopFieldCollector in project neo4j by neo4j.
the class TopDocsIterator method toTopDocs.
private TopDocs toTopDocs(Query query, QueryContext context, IndexSearcher searcher) throws IOException {
Sort sorting = context != null ? context.getSorting() : null;
TopDocs topDocs;
if (sorting == null && context != null) {
topDocs = searcher.search(query, context.getTop());
} else {
if (context == null || !context.getTradeCorrectnessForSpeed()) {
TopFieldCollector collector = LuceneDataSource.scoringCollector(sorting, context.getTop());
searcher.search(query, collector);
topDocs = collector.topDocs();
} else {
topDocs = searcher.search(query, null, context.getTop(), sorting);
}
}
return topDocs;
}
Aggregations