@Override public ResourceIterator<Node> findNodes( final Label myLabel, final String key, final String value, final StringSearchMode searchMode ) { KernelTransaction transaction = statementContext.getKernelTransactionBoundToThisThread( true ); TokenRead tokenRead = transaction.tokenRead(); int labelId = tokenRead.nodeLabel( myLabel.name() ); int propertyId = tokenRead.propertyKey( key ); IndexQuery query; switch ( searchMode ) { case EXACT: query = IndexQuery.exact( propertyId, utf8Value( value.getBytes( UTF_8 ) ) ); break; case PREFIX: query = IndexQuery.stringPrefix( propertyId, utf8Value( value.getBytes( UTF_8 ) ) ); break; case SUFFIX: query = IndexQuery.stringSuffix( propertyId, utf8Value( value.getBytes( UTF_8 ) ) ); break; case CONTAINS: query = IndexQuery.stringContains( propertyId, utf8Value( value.getBytes( UTF_8 ) ) ); break; default: throw new IllegalStateException( "Unknown string search mode: " + searchMode ); } return nodesByLabelAndProperty( transaction, labelId, query ); }
@Override protected boolean acceptValue( Value[] values ) { for ( int i = 0; i < values.length; i++ ) { if ( !filter[i].acceptsValue( values[i] ) ) { return false; } } return true; }
private static boolean isNumericOrGeometricPredicate( IndexQuery predicate ) { if ( predicate.type() == IndexQuery.IndexQueryType.exact ) { IndexQuery.ExactPredicate exactPredicate = (IndexQuery.ExactPredicate) predicate; return isNumberGeometryOrArray( exactPredicate.value() ); } else { return predicate.type() == IndexQuery.IndexQueryType.range && (predicate.valueGroup() == ValueGroup.NUMBER || predicate.valueGroup() == ValueGroup.GEOMETRY); } }
/** * Run the Value[] from a particular entityId through the list of IndexQuery[] predicates to see if they all accept the value. */ private boolean passesFilter( long entityId, IndexQuery[] predicates ) { if ( predicates.length == 1 && predicates[0] instanceof IndexQuery.ExistsPredicate ) { return true; } Value[] values = committedValues.get( entityId ); for ( int i = 0; i < values.length; i++ ) { IndexQuery predicate = predicates[i]; if ( predicate.valueGroup() == ValueGroup.GEOMETRY || predicate.valueGroup() == ValueGroup.GEOMETRY_ARRAY || (predicate.valueGroup() == ValueGroup.NUMBER && !testSuite.supportFullValuePrecisionForNumbers()) ) { if ( !predicates[i].acceptsValue( values[i] ) ) { return false; } } // else there's no functional need to let values, other than those of GEOMETRY type, to pass through the IndexQuery filtering // avoiding this filtering will have testing be more strict in what index readers returns. } return true; }
int propertyKeyId = predicate.propertyKeyId(); Value value = accessor.getNodePropertyValue( nodeId, propertyKeyId ); if ( !predicate.acceptsValue( value ) )
@Test public void testIndexSeekAndScan() throws Exception { updateAndCommit( asList( add( 1L, descriptor.schema(), "a" ), add( 2L, descriptor.schema(), "b" ), add( 3L, descriptor.schema(), "c" ) ) ); assertThat( query( exact( 1, "a" ) ), equalTo( singletonList( 1L ) ) ); assertThat( query( IndexQuery.exists( 1 ) ), equalTo( asList( 1L, 2L, 3L ) ) ); } }
@Test public void testGeometryRange_FalseForIrrelevant() { RangePredicate<?> p = IndexQuery.range( propId, gps2, true, gps5, true ); assertFalseForOtherThings( p ); }
@Test void prefixRangeSeekQueryReachSearcher() throws Exception { IndexReader simpleIndexReader = getUniqueSimpleReader(); simpleIndexReader.query( IndexQuery.stringPrefix( 1, stringValue( "bb" ) ) ); verify( indexSearcher ).search( any( MultiTermQuery.class ), any( DocValuesCollector.class ) ); }
@Test public void testIndexSeekPrefixRangeWithExistsByString() throws Exception { Assume.assumeTrue( "Assume support for granular composite queries", testSuite.supportsGranularCompositeQueries() ); updateAndCommit( asList( add( 1L, descriptor.schema(), "a", 1 ), add( 2L, descriptor.schema(), "A", epochDate( 2 ) ), add( 3L, descriptor.schema(), "apa", "..." ), add( 4L, descriptor.schema(), "apA", "someString" ), add( 5L, descriptor.schema(), "b", true ), add( 6L, descriptor.schema(), "a", 100 ), add( 7L, descriptor.schema(), "A", epochDate( 200 ) ), add( 8L, descriptor.schema(), "apa", "!!!" ), add( 9L, descriptor.schema(), "apA", "someOtherString" ), add( 10L, descriptor.schema(), "b", false ) ) ); assertThat( query( IndexQuery.stringPrefix( 0, stringValue( "a" )), exists( 1 ) ), equalTo( asList( 1L, 3L, 4L, 6L, 8L, 9L ) ) ); assertThat( query( IndexQuery.stringPrefix( 0, stringValue( "A" )), exists( 1 ) ), equalTo( asList( 2L, 7L) ) ); assertThat( query( IndexQuery.stringPrefix( 0, stringValue( "ba") ), exists( 1 ) ), equalTo( EMPTY_LIST ) ); assertThat( query( IndexQuery.stringPrefix( 0, stringValue( "" )), exists( 1 ) ), equalTo( asList( 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L ) ) ); }
@Test public void testStringContains_FalseForIrrelevant() { StringContainsPredicate p = IndexQuery.stringContains( propId, stringValue( "cat" )); assertFalseForOtherThings( p ); }
@Test public void testStringSuffix_FalseForIrrelevant() { StringSuffixPredicate p = IndexQuery.stringSuffix( propId, stringValue( "less" ) ); assertFalseForOtherThings( p ); }
@Override public boolean hasFullValuePrecision( IndexQuery... predicates ) { for ( IndexQuery predicate : predicates ) { ValueGroup valueGroup = predicate.valueGroup(); if ( valueGroup == ValueGroup.GEOMETRY_ARRAY || valueGroup == ValueGroup.GEOMETRY ) { return false; } } return true; }
@Override NodeValueIndexCursor queryExact( KernelTransaction ktx ) throws KernelException { return indexQuery( ktx, indexDescriptor, IndexQuery.exact( stringPropId1, stringProp1Values[0] ) ); }
@Test public void testIndexSeekAndScan() throws Exception { updateAndCommit( asList( add( 1L, descriptor.schema(), "a" ), add( 2L, descriptor.schema(), "a" ), add( 3L, descriptor.schema(), "b" ) ) ); assertThat( query( exact( 1, "a" ) ), equalTo( asList( 1L, 2L ) ) ); assertThat( query( exists( 1 ) ), equalTo( asList( 1L, 2L, 3L ) ) ); }
@Test public void testNumRange_FalseForIrrelevant() { RangePredicate<?> p = IndexQuery.range( propId, 11, true, 13, true ); assertFalseForOtherThings( p ); }
@Test public void testStringPrefix_FalseForIrrelevant() { StringPrefixPredicate p = IndexQuery.stringPrefix( propId, stringValue( "dog" ) ); assertFalseForOtherThings( p ); }
@Test public void mustSelectStringForStringContainsPredicate() throws Exception { // given StringContainsPredicate stringContains = IndexQuery.stringContains( PROP_KEY, stringValue( "abc" ) ); // then verifyQueryWithCorrectReader( expectedForStrings(), stringContains ); }
@Test public void mustSelectStringForStringSuffixPredicate() throws Exception { // given StringSuffixPredicate stringPrefix = IndexQuery.stringSuffix( PROP_KEY, stringValue( "abc" ) ); // then verifyQueryWithCorrectReader( expectedForStrings(), stringPrefix ); }