Skip to content

Commit

Permalink
Add index query methods for range by value group and range by CRS
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed Mar 13, 2018
1 parent 3759b1e commit da8dcbf
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 11 deletions.
Expand Up @@ -92,14 +92,43 @@ public static <VALUE extends Value> RangePredicate range( int propertyKeyId,
VALUE from, boolean fromInclusive,
VALUE to, boolean toInclusive )
{
if ( from == null && to == null )
{
throw new IllegalArgumentException( "Cannot create RangePredicate without at least one bound" );
}

ValueGroup valueGroup = from != null ? from.valueGroup() : to.valueGroup();
if ( valueGroup == ValueGroup.GEOMETRY )
{
return new GeometryRangePredicate( propertyKeyId, (PointValue)from, fromInclusive, (PointValue)to, toInclusive );
PointValue pFrom = (PointValue)from;
PointValue pTo = (PointValue)to;
CoordinateReferenceSystem crs = pFrom != null ? pFrom.getCoordinateReferenceSystem() : pTo.getCoordinateReferenceSystem();
return new GeometryRangePredicate( propertyKeyId, crs, pFrom, fromInclusive, pTo, toInclusive );
}
return new RangePredicate<>( propertyKeyId, valueGroup, from, fromInclusive, to, toInclusive );
}

/**
* Create IndexQuery for retrieving all indexed entries of the given value group.
*/
public static RangePredicate range( int propertyKeyId, ValueGroup valueGroup )
{
if ( valueGroup == ValueGroup.GEOMETRY )
{
throw new IllegalArgumentException( "Cannot create GeometryRangePredicate without at specified CRS" );
}
return new RangePredicate<>( propertyKeyId, valueGroup, null, true, null, true );
}

/**
* Create IndexQuery for retrieving all indexed entries with spatial value of the given
* coordinate reference system.
*/
public static RangePredicate range( int propertyKeyId, CoordinateReferenceSystem crs )
{
return new GeometryRangePredicate( propertyKeyId, crs, null, true, null, true );
}

/**
* Searches the index string values starting with {@code prefix}.
*
Expand Down Expand Up @@ -305,15 +334,15 @@ public boolean acceptsValue( Value value )
}
if ( value.valueGroup() == valueGroup )
{
if ( from != NO_VALUE )
if ( from != null )
{
int compare = Values.COMPARATOR.compare( value, from );
if ( compare < 0 || !fromInclusive && compare == 0 )
{
return false;
}
}
if ( to != NO_VALUE )
if ( to != null )
{
int compare = Values.COMPARATOR.compare( value, to );
if ( compare > 0 || !toInclusive && compare == 0 )
Expand Down Expand Up @@ -357,14 +386,10 @@ public static final class GeometryRangePredicate extends RangePredicate<PointVal
{
private final CoordinateReferenceSystem crs;

GeometryRangePredicate( int propertyKeyId, PointValue from, boolean fromInclusive, PointValue to, boolean toInclusive )
GeometryRangePredicate( int propertyKeyId, CoordinateReferenceSystem crs, PointValue from, boolean fromInclusive, PointValue to, boolean toInclusive )
{
super( propertyKeyId, ValueGroup.GEOMETRY, from, fromInclusive, to, toInclusive );
if ( from == null && to == null )
{
throw new IllegalArgumentException( "Cannot create GeometryRangePredicate without at least one bound" );
}
this.crs = from != null ? from.getCoordinateReferenceSystem() : to.getCoordinateReferenceSystem();
this.crs = crs;
}

@Override
Expand All @@ -377,7 +402,10 @@ public boolean acceptsValue( Value value )
if ( value instanceof PointValue )
{
PointValue point = (PointValue) value;
return point.withinRange( from, fromInclusive, to, toInclusive );
if ( point.getCRS() == crs )
{
return point.withinRange( from, fromInclusive, to, toInclusive );
}
}
return false;
}
Expand Down
Expand Up @@ -21,14 +21,21 @@

import org.junit.Test;

import java.time.ZoneOffset;

import org.neo4j.internal.kernel.api.IndexQuery.ExactPredicate;
import org.neo4j.internal.kernel.api.IndexQuery.ExistsPredicate;
import org.neo4j.internal.kernel.api.IndexQuery.RangePredicate;
import org.neo4j.internal.kernel.api.IndexQuery.StringContainsPredicate;
import org.neo4j.internal.kernel.api.IndexQuery.StringPrefixPredicate;
import org.neo4j.internal.kernel.api.IndexQuery.StringSuffixPredicate;
import org.neo4j.values.storable.CoordinateReferenceSystem;
import org.neo4j.values.storable.DateTimeValue;
import org.neo4j.values.storable.DateValue;
import org.neo4j.values.storable.LocalDateTimeValue;
import org.neo4j.values.storable.PointValue;
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.ValueGroup;
import org.neo4j.values.storable.Values;

import static org.junit.Assert.assertFalse;
Expand Down Expand Up @@ -409,6 +416,45 @@ public void testGeometryRange_WGS84_3D()
assertTrue( test( p, gps2_3d ) );
}

@Test
public void testDateRange()
{
RangePredicate p = IndexQuery.range( propId, DateValue.date( 2014, 7, 7 ), true, DateValue.date( 2017,3, 7 ), false );

assertFalse( test( p, DateValue.date( 2014, 6, 8 ) ) );
assertTrue( test( p, DateValue.date( 2014, 7, 7 ) ) );
assertTrue( test( p, DateValue.date( 2016, 6, 8 ) ) );
assertFalse( test( p, DateValue.date( 2017, 3, 7 ) ) );
assertFalse( test( p, DateValue.date( 2017, 3, 8 ) ) );
assertFalse( test( p, LocalDateTimeValue.localDateTime( 2016, 3, 8, 0, 0, 0, 0 ) ) );
}

// VALUE GROUP SCAN
@Test
public void testValueGroupRange()
{
RangePredicate p = IndexQuery.range( propId, ValueGroup.DATE );

assertTrue( test( p, DateValue.date( -4000, 1, 31 ) ) );
assertTrue( test( p, DateValue.date( 2018, 3, 7 ) ) );
assertFalse( test( p, DateTimeValue.datetime( 2018, 3, 7, 0, 0, 0, 0, ZoneOffset.UTC ) ) );
assertFalse( test( p, Values.stringValue( "hej" ) ) );
assertFalse( test( p, gps2_3d ) );
}

@Test
public void testCRSRange()
{
RangePredicate p = IndexQuery.range( propId, CoordinateReferenceSystem.WGS84 );

assertTrue( test( p, gps2 ) );
assertFalse( test( p, DateValue.date( -4000, 1, 31 ) ) );
assertFalse( test( p, Values.stringValue( "hej" ) ) );
assertFalse( test( p, car1 ) );
assertFalse( test( p, car4 ) );
assertFalse( test( p, gps1_3d ) );
}

// STRING PREFIX

@Test
Expand Down Expand Up @@ -492,6 +538,6 @@ private void assertFalseForOtherThings( IndexQuery p )

private boolean test( IndexQuery p, Object x )
{
return p.acceptsValue( Values.of( x ) );
return p.acceptsValue( x instanceof Value ? (Value)x : Values.of( x ) );
}
}

0 comments on commit da8dcbf

Please sign in to comment.