Permalink
Browse files

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

…queried value was a numeric value (via ValueContext#numeric)
  • Loading branch information...
1 parent 94294ea commit 4d11af57297faf524ffd1d233a3ebf3f4af78186 @tinwelint committed with digitalstain Mar 23, 2012
@@ -41,6 +41,7 @@
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 @@ public Query deletionQuery( long entityId, String key, Object value )
@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 @@ public Query deletionQuery( long entityId, String key, Object value )
@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 @@ private String exactKey( String key )
@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 @@ Similarity getSimilarity()
{
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 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 @@ static void strictRemoveDocument( IndexWriter writer, Query query )
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 @@
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 static QueryContext numericRange( String key, Number from, Number to )
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 ) );
}
}
@@ -1619,4 +1619,28 @@ public void getOrCreateMultiThreaded() throws Exception
assertEquals( node, index.get( key, value ).getSingle() );
}
+
+ @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() );
+ }
}

0 comments on commit 4d11af5

Please sign in to comment.