Commit 549ec242 authored by Mattias Persson's avatar Mattias Persson Committed by Chris Gioran
Browse files

Fixed an issue where a 'get' on a lucene index wouldn't honor if the queried...

Fixed an issue where a 'get' on a lucene index wouldn't honor if the queried value was a numeric value (via ValueContext#numeric)
parent 4203f4fe
No related merge requests found
Showing with 91 additions and 25 deletions
+91 -25
......@@ -41,6 +41,7 @@ import org.apache.lucene.search.Similarity;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.Version;
import org.neo4j.index.lucene.QueryContext;
import org.neo4j.index.lucene.ValueContext;
abstract class IndexType
{
......@@ -58,7 +59,7 @@ abstract class IndexType
@Override
public Query get( String key, Object value )
{
return new TermQuery( new Term( key, value.toString() ) );
return queryForGet( key, value );
}
@Override
......@@ -125,6 +126,8 @@ abstract class IndexType
@Override
public Query get( String key, Object value )
{
// TODO we do value.toString() here since initially #addToDocument didn't
// honor ValueContext, and changing it would mean changing store format.
return new TermQuery( new Term( exactKey( key ), value.toString() ) );
}
......@@ -136,6 +139,8 @@ abstract class IndexType
@Override
public void addToDocument( Document document, String key, Object value )
{
// TODO We should honor ValueContext instead of doing value.toString() here.
// if changing it, also change #get to honor ValueContext.
document.add( new Field( exactKey( key ), value.toString(), Store.YES, Index.NOT_ANALYZED ) );
document.add( instantiateField( key, value, Index.ANALYZED ) );
}
......@@ -370,4 +375,18 @@ abstract class IndexType
{
return null;
}
Query queryForGet( String key, Object value )
{
if ( value instanceof ValueContext )
{
Object realValue = ((ValueContext)value).getValue();
if ( realValue instanceof Number )
{
Number number = (Number) realValue;
return LuceneUtil.rangeQuery( key, number, number, true, true );
}
}
return new TermQuery( new Term( key, value.toString() ) );
}
}
......@@ -24,9 +24,11 @@ import java.io.IOException;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.neo4j.index.lucene.ValueContext;
abstract class LuceneUtil
public abstract class LuceneUtil
{
static void close( IndexWriter writer )
{
......@@ -85,4 +87,46 @@ abstract class LuceneUtil
throw new RuntimeException( e );
}
}
/**
* Will create a {@link Query} with a query for numeric ranges, that is
* values that have been indexed using {@link ValueContext#indexNumeric()}.
* It will match the type of numbers supplied to the type of values that
* are indexed in the index, f.ex. long, int, float and double.
* If both {@code from} and {@code to} is {@code null} then it will default
* to int.
*
* @param key the property key to query.
* @param from the low end of the range (inclusive)
* @param to the high end of the range (inclusive)
* @param includeFrom whether or not {@code from} (the lower bound) is inclusive
* or not.
* @param includeTo whether or not {@code to} (the higher bound) is inclusive
* or not.
* @return a {@link Query} to do numeric range queries with.
*/
public static Query rangeQuery( String key, Number from, Number to,
boolean includeFrom, boolean includeTo )
{
if ( from instanceof Long )
{
return NumericRangeQuery.newLongRange( key, from != null ? from.longValue() : 0,
to != null ? to.longValue() : Long.MAX_VALUE, includeFrom, includeTo );
}
else if ( from instanceof Double )
{
return NumericRangeQuery.newDoubleRange( key, from != null ? from.doubleValue() : 0,
to != null ? to.doubleValue() : Double.MAX_VALUE, includeFrom, includeTo );
}
else if ( from instanceof Float )
{
return NumericRangeQuery.newFloatRange( key, from != null ? from.floatValue() : 0,
to != null ? to.floatValue() : Float.MAX_VALUE, includeFrom, includeTo );
}
else
{
return NumericRangeQuery.newIntRange( key, from != null ? from.intValue() : 0,
to != null ? to.intValue() : Integer.MAX_VALUE, includeFrom, includeTo );
}
}
}
......@@ -22,11 +22,11 @@ package org.neo4j.index.lucene;
import org.apache.lucene.queryParser.QueryParser.Operator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.index.IndexHits;
import org.neo4j.index.impl.lucene.LuceneUtil;
/**
* This class has the extra query configuration to use
......@@ -266,27 +266,6 @@ public class QueryContext
public static QueryContext numericRange( String key, Number from, Number to,
boolean includeFrom, boolean includeTo )
{
Query query = null;
if ( from instanceof Long )
{
query = NumericRangeQuery.newLongRange( key, from != null ? from.longValue() : 0,
to != null ? to.longValue() : Long.MAX_VALUE, includeFrom, includeTo );
}
else if ( from instanceof Double )
{
query = NumericRangeQuery.newDoubleRange( key, from != null ? from.doubleValue() : 0,
to != null ? to.doubleValue() : Double.MAX_VALUE, includeFrom, includeTo );
}
else if ( from instanceof Float )
{
query = NumericRangeQuery.newFloatRange( key, from != null ? from.floatValue() : 0,
to != null ? to.floatValue() : Float.MAX_VALUE, includeFrom, includeTo );
}
else
{
query = NumericRangeQuery.newIntRange( key, from != null ? from.intValue() : 0,
to != null ? to.intValue() : Integer.MAX_VALUE, includeFrom, includeTo );
}
return new QueryContext( query );
return new QueryContext( LuceneUtil.rangeQuery( key, from, to, includeFrom, includeTo ) );
}
}
......@@ -1644,4 +1644,28 @@ public class TestLuceneIndex extends AbstractLuceneIndexTest
Node node = graphDb.createNode();
index.add( node, "name", "Mattias" );
}
@Test
public void numericValueForGetInExactIndex() throws Exception
{
Index<Node> index = nodeIndex( testname.getMethodName(), LuceneIndexImplementation.EXACT_CONFIG );
numericValueForGet( index );
}
@Test
public void numericValueForGetInFulltextIndex() throws Exception
{
Index<Node> index = nodeIndex( testname.getMethodName(), LuceneIndexImplementation.FULLTEXT_CONFIG );
numericValueForGet( index );
}
private void numericValueForGet( Index<Node> index )
{
Node node = graphDb.createNode();
long id = 100L;
index.add( node, "name", ValueContext.numeric( id ) );
assertEquals( node, index.get( "name", ValueContext.numeric( id ) ).getSingle() );
restartTx();
assertEquals( node, index.get( "name", ValueContext.numeric( id ) ).getSingle() );
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment