Skip to content

Commit

Permalink
Optimize search for when only one result is required
Browse files Browse the repository at this point in the history
  • Loading branch information
knutwalker authored and MishaDemianenko committed Dec 5, 2015
1 parent ee0e358 commit 663c643
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 5 deletions.
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2002-2015 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.kernel.api.impl.index;

import org.apache.lucene.search.CollectionTerminatedException;
import org.apache.lucene.search.SimpleCollector;

import java.io.IOException;

/**
* A {@code Collector} that terminates the collection after the very first hit.
* As a consequence, additional collectors in this search that require a complete run over the index,
* such as {@code TotalHitCountCollector} or {@link DocValuesCollector}, won't work as expected.
*/
public final class FirstHitCollector extends SimpleCollector
{
public static final int NO_MATCH = -1;

private int result = NO_MATCH;

/**
* @return true when this collector got a match, otherwise false.
*/
public boolean hasMatched()
{
return result != NO_MATCH;
}

/**
* @return the docId if this collector got a match, otherwise {@link FirstHitCollector#NO_MATCH}.
*/
public int getMatchedDoc()
{
return result;
}

@Override
public void collect( int doc ) throws IOException
{
result = doc;
throw new CollectionTerminatedException();
}

@Override
public boolean needsScores()
{
return false;
}
}
Expand Up @@ -24,7 +24,6 @@
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;

import java.io.IOException;
import java.util.ArrayList;
Expand Down Expand Up @@ -110,12 +109,14 @@ public void close() throws IOException

private Map<Long/*range*/, Bitmap> readLabelBitMapsInRange( IndexSearcher searcher, long range ) throws IOException
{
Map<Long/*label*/, Bitmap> fields = new HashMap<>();
Map<Long/*label*/,Bitmap> fields = new HashMap<>();
Term documentTerm = format.rangeTerm( range );
TopDocs docs = searcher.search( new TermQuery( documentTerm ), 1 );
if ( docs != null && docs.totalHits != 0 )
TermQuery query = new TermQuery( documentTerm );
FirstHitCollector hitCollector = new FirstHitCollector();
searcher.search( query, hitCollector );
if ( hitCollector.hasMatched() )
{
Document document = searcher.doc( docs.scoreDocs[0].doc );
Document document = searcher.doc( hitCollector.getMatchedDoc() );
for ( IndexableField field : document.getFields() )
{
if ( !format.isRangeField( field ) )
Expand Down

0 comments on commit 663c643

Please sign in to comment.