Search in sources :

Example 16 with PropertyIndexQuery

use of org.neo4j.internal.kernel.api.PropertyIndexQuery in project neo4j by neo4j.

the class CompositeIndexAccessorCompatibility method mustThrowOnIllegalCompositeQueriesAndMustNotThrowOnLegalQueries.

/* Composite query validity */
/**
 * This test verify behavior for all different index patterns on a two column composite index.
 * A composite query need to have decreasing precision among the queries.
 * This means a range or exists query can only be followed by and exists query.
 * Prefix query is also included under "range".
 * Contains or suffix queries are not allowed in a composite query at all.
 *
 * Those are all the different combinations:
 * x = exact
 * < = range (also include stringPrefix)
 * - = exists
 * ! = stringContains or stringSuffix
 * ? = any predicate
 * Index patterns
 * x x ok
 * x < ok
 * x - ok
 * < x not ok
 * < < not ok
 * < - ok
 * - x not ok
 * - < not ok
 * - - ok
 * ! ? not ok
 */
@Test
public void mustThrowOnIllegalCompositeQueriesAndMustNotThrowOnLegalQueries() throws Exception {
    Assume.assumeTrue("Assume support for granular composite queries", testSuite.supportsGranularCompositeQueries());
    // given
    Value someValue = Values.of(true);
    TextValue someString = stringValue("");
    PropertyIndexQuery firstExact = exact(100, someValue);
    PropertyIndexQuery firstRange = range(100, someValue, true, someValue, true);
    PropertyIndexQuery firstPrefix = stringPrefix(100, someString);
    PropertyIndexQuery firstExist = exists(100);
    PropertyIndexQuery firstSuffix = stringSuffix(100, someString);
    PropertyIndexQuery firstContains = stringContains(100, someString);
    PropertyIndexQuery secondExact = exact(200, someValue);
    PropertyIndexQuery secondRange = range(200, someValue, true, someValue, true);
    PropertyIndexQuery secondExist = exists(200);
    PropertyIndexQuery secondPrefix = stringPrefix(100, someString);
    PropertyIndexQuery secondSuffix = stringSuffix(100, someString);
    PropertyIndexQuery secondContains = stringContains(100, someString);
    List<Pair<PropertyIndexQuery[], Boolean>> queries = Arrays.asList(of(new PropertyIndexQuery[] { firstExact, secondExact }, true), of(new PropertyIndexQuery[] { firstExact, secondRange }, true), of(new PropertyIndexQuery[] { firstExact, secondExist }, true), of(new PropertyIndexQuery[] { firstExact, secondPrefix }, true), of(new PropertyIndexQuery[] { firstExact, secondSuffix }, false), of(new PropertyIndexQuery[] { firstExact, secondContains }, false), of(new PropertyIndexQuery[] { firstRange, secondExact }, false), of(new PropertyIndexQuery[] { firstRange, secondRange }, false), of(new PropertyIndexQuery[] { firstRange, secondExist }, true), of(new PropertyIndexQuery[] { firstRange, secondPrefix }, false), of(new PropertyIndexQuery[] { firstRange, secondSuffix }, false), of(new PropertyIndexQuery[] { firstRange, secondContains }, false), of(new PropertyIndexQuery[] { firstPrefix, secondExact }, false), of(new PropertyIndexQuery[] { firstPrefix, secondRange }, false), of(new PropertyIndexQuery[] { firstPrefix, secondExist }, true), of(new PropertyIndexQuery[] { firstPrefix, secondPrefix }, false), of(new PropertyIndexQuery[] { firstPrefix, secondSuffix }, false), of(new PropertyIndexQuery[] { firstPrefix, secondContains }, false), of(new PropertyIndexQuery[] { firstExist, secondExact }, false), of(new PropertyIndexQuery[] { firstExist, secondRange }, false), of(new PropertyIndexQuery[] { firstExist, secondExist }, true), of(new PropertyIndexQuery[] { firstExist, secondPrefix }, false), of(new PropertyIndexQuery[] { firstExist, secondSuffix }, false), of(new PropertyIndexQuery[] { firstExist, secondContains }, false), of(new PropertyIndexQuery[] { firstSuffix, secondExact }, false), of(new PropertyIndexQuery[] { firstSuffix, secondRange }, false), of(new PropertyIndexQuery[] { firstSuffix, secondExist }, false), of(new PropertyIndexQuery[] { firstSuffix, secondPrefix }, false), of(new PropertyIndexQuery[] { firstSuffix, secondSuffix }, false), of(new PropertyIndexQuery[] { firstSuffix, secondContains }, false), of(new PropertyIndexQuery[] { firstContains, secondExact }, false), of(new PropertyIndexQuery[] { firstContains, secondRange }, false), of(new PropertyIndexQuery[] { firstContains, secondExist }, false), of(new PropertyIndexQuery[] { firstContains, secondPrefix }, false), of(new PropertyIndexQuery[] { firstContains, secondSuffix }, false), of(new PropertyIndexQuery[] { firstContains, secondContains }, false));
    SimpleEntityValueClient client = new SimpleEntityValueClient();
    try (ValueIndexReader reader = accessor.newValueReader()) {
        for (Pair<PropertyIndexQuery[], Boolean> pair : queries) {
            PropertyIndexQuery[] theQuery = pair.first();
            Boolean legal = pair.other();
            if (legal) {
                // when
                reader.query(NULL_CONTEXT, client, unconstrained(), theQuery);
            // then should not throw
            } else {
                try {
                    // when
                    reader.query(NULL_CONTEXT, client, unconstrained(), theQuery);
                    fail("Expected index reader to throw for illegal composite query. Query was, " + Arrays.toString(theQuery));
                } catch (IllegalArgumentException e) {
                    // then
                    assertThat(e.getMessage()).contains("Tried to query index with illegal composite query.");
                }
            }
        }
    }
}
Also used : PropertyIndexQuery(org.neo4j.internal.kernel.api.PropertyIndexQuery) TextValue(org.neo4j.values.storable.TextValue) ArrayValue(org.neo4j.values.storable.ArrayValue) Value(org.neo4j.values.storable.Value) TextValue(org.neo4j.values.storable.TextValue) PointValue(org.neo4j.values.storable.PointValue) LocalDateTimeValue(org.neo4j.values.storable.LocalDateTimeValue) TimeValue(org.neo4j.values.storable.TimeValue) DateTimeValue(org.neo4j.values.storable.DateTimeValue) Values.intValue(org.neo4j.values.storable.Values.intValue) Values.pointValue(org.neo4j.values.storable.Values.pointValue) LocalTimeValue(org.neo4j.values.storable.LocalTimeValue) BooleanValue(org.neo4j.values.storable.BooleanValue) Values.stringValue(org.neo4j.values.storable.Values.stringValue) DateValue(org.neo4j.values.storable.DateValue) SimpleEntityValueClient(org.neo4j.storageengine.api.schema.SimpleEntityValueClient) Pair(org.neo4j.internal.helpers.collection.Pair) Test(org.junit.Test)

Example 17 with PropertyIndexQuery

use of org.neo4j.internal.kernel.api.PropertyIndexQuery in project neo4j by neo4j.

the class IndexOrderTestBase method shouldRangeScanInOrderWithTxState.

@ParameterizedTest
@EnumSource(value = IndexOrder.class, names = { "ASCENDING", "DESCENDING" })
void shouldRangeScanInOrderWithTxState(IndexOrder indexOrder) throws Exception {
    List<Pair<Long, Value>> expected = new ArrayList<>();
    try (KernelTransaction tx = beginTransaction()) {
        expected.add(entityWithProp(tx, "hello"));
        entityWithProp(tx, "bellow");
        expected.add(entityWithProp(tx, "schmello"));
        expected.add(entityWithProp(tx, "low"));
        expected.add(entityWithProp(tx, "trello"));
        entityWithProp(tx, "yellow");
        expected.add(entityWithProp(tx, "loww"));
        entityWithProp(tx, "below");
        tx.commit();
    }
    createIndex();
    // when
    try (KernelTransaction tx = beginTransaction()) {
        int prop = tx.tokenRead().propertyKey(DEFAULT_PROPERTY_NAME);
        IndexReadSession index = tx.dataRead().indexReadSession(tx.schemaRead().indexGetForName(INDEX_NAME));
        try (var cursor = getEntityValueIndexCursor(tx)) {
            entityWithProp(tx, "allow");
            expected.add(entityWithProp(tx, "now"));
            expected.add(entityWithProp(tx, "jello"));
            entityWithProp(tx, "willow");
            PropertyIndexQuery query = PropertyIndexQuery.range(prop, "hello", true, "trello", true);
            entityIndexSeek(tx, index, cursor, constrained(indexOrder, true), query);
            assertResultsInOrder(expected, cursor, indexOrder);
        }
    }
}
Also used : KernelTransaction(org.neo4j.kernel.api.KernelTransaction) PropertyIndexQuery(org.neo4j.internal.kernel.api.PropertyIndexQuery) ArrayList(java.util.ArrayList) Pair(org.neo4j.internal.helpers.collection.Pair) IndexReadSession(org.neo4j.internal.kernel.api.IndexReadSession) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 18 with PropertyIndexQuery

use of org.neo4j.internal.kernel.api.PropertyIndexQuery in project neo4j by neo4j.

the class IndexOrderTestBase method shouldPrefixScanInOrder.

@ParameterizedTest
@EnumSource(value = IndexOrder.class, names = { "ASCENDING", "DESCENDING" })
void shouldPrefixScanInOrder(IndexOrder indexOrder) throws Exception {
    List<Pair<Long, Value>> expected = new ArrayList<>();
    try (KernelTransaction tx = beginTransaction()) {
        expected.add(entityWithProp(tx, "bee hive"));
        entityWithProp(tx, "a");
        expected.add(entityWithProp(tx, "become"));
        expected.add(entityWithProp(tx, "be"));
        expected.add(entityWithProp(tx, "bachelor"));
        entityWithProp(tx, "street smart");
        expected.add(entityWithProp(tx, "builder"));
        entityWithProp(tx, "ceasar");
        tx.commit();
    }
    createIndex();
    // when
    try (KernelTransaction tx = beginTransaction()) {
        int prop = tx.tokenRead().propertyKey(DEFAULT_PROPERTY_NAME);
        IndexReadSession index = tx.dataRead().indexReadSession(tx.schemaRead().indexGetForName(INDEX_NAME));
        try (var cursor = getEntityValueIndexCursor(tx)) {
            entityWithProp(tx, "allow");
            expected.add(entityWithProp(tx, "bastard"));
            expected.add(entityWithProp(tx, "bully"));
            entityWithProp(tx, "willow");
            PropertyIndexQuery query = PropertyIndexQuery.stringPrefix(prop, stringValue("b"));
            entityIndexSeek(tx, index, cursor, constrained(indexOrder, true), query);
            assertResultsInOrder(expected, cursor, indexOrder);
        }
    }
}
Also used : KernelTransaction(org.neo4j.kernel.api.KernelTransaction) PropertyIndexQuery(org.neo4j.internal.kernel.api.PropertyIndexQuery) ArrayList(java.util.ArrayList) Pair(org.neo4j.internal.helpers.collection.Pair) IndexReadSession(org.neo4j.internal.kernel.api.IndexReadSession) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 19 with PropertyIndexQuery

use of org.neo4j.internal.kernel.api.PropertyIndexQuery in project neo4j by neo4j.

the class SchemaComplianceChecker method verifyIndexedUniquely.

private <ENTITY extends PrimitiveRecord> void verifyIndexedUniquely(ENTITY entity, Value[] propertyValues, IndexDescriptor indexRule, ValueIndexReader reader, Function<ENTITY, ConsistencyReport.PrimitiveConsistencyReport> reportSupplier) {
    long nodeId = entity.getId();
    PropertyIndexQuery[] query = seek(indexRule.schema(), propertyValues);
    LongIterator indexedNodeIds = queryIndexOrEmpty(reader, query);
    long count = 0;
    while (indexedNodeIds.hasNext()) {
        long indexedNodeId = indexedNodeIds.next();
        if (nodeId == indexedNodeId) {
            count++;
        } else {
            reportSupplier.apply(entity).uniqueIndexNotUnique(indexRule, Values.asObjects(propertyValues), indexedNodeId);
        }
    }
    reportIncorrectIndexCount(entity, propertyValues, indexRule, count, reportSupplier);
}
Also used : PropertyIndexQuery(org.neo4j.internal.kernel.api.PropertyIndexQuery) LongIterator(org.eclipse.collections.api.iterator.LongIterator)

Example 20 with PropertyIndexQuery

use of org.neo4j.internal.kernel.api.PropertyIndexQuery in project neo4j by neo4j.

the class FulltextIndexReader method query.

@Override
public void query(QueryContext context, IndexProgressor.EntityValueClient client, IndexQueryConstraints constraints, PropertyIndexQuery... queries) throws IndexNotApplicableKernelException {
    BooleanQuery.Builder queryBuilder = new BooleanQuery.Builder();
    for (PropertyIndexQuery indexQuery : queries) {
        if (indexQuery.type() == PropertyIndexQuery.IndexQueryType.fulltextSearch) {
            PropertyIndexQuery.FulltextSearchPredicate fulltextSearch = (PropertyIndexQuery.FulltextSearchPredicate) indexQuery;
            try {
                queryBuilder.add(parseFulltextQuery(fulltextSearch.query()), BooleanClause.Occur.SHOULD);
            } catch (ParseException e) {
                throw new RuntimeException("Could not parse the given fulltext search query: '" + fulltextSearch.query() + "'.", e);
            }
        } else {
            // Not fulltext query
            assertNotComposite(queries);
            assertCypherCompatible();
            Query query;
            if (indexQuery.type() == PropertyIndexQuery.IndexQueryType.stringContains) {
                PropertyIndexQuery.StringContainsPredicate scp = (PropertyIndexQuery.StringContainsPredicate) indexQuery;
                String searchTerm = QueryParser.escape(scp.contains().stringValue());
                Term term = new Term(propertyNames[0], "*" + searchTerm + "*");
                query = new WildcardQuery(term);
            } else if (indexQuery.type() == PropertyIndexQuery.IndexQueryType.stringSuffix) {
                PropertyIndexQuery.StringSuffixPredicate ssp = (PropertyIndexQuery.StringSuffixPredicate) indexQuery;
                String searchTerm = QueryParser.escape(ssp.suffix().stringValue());
                Term term = new Term(propertyNames[0], "*" + searchTerm);
                query = new WildcardQuery(term);
            } else if (indexQuery.type() == PropertyIndexQuery.IndexQueryType.stringPrefix) {
                PropertyIndexQuery.StringPrefixPredicate spp = (PropertyIndexQuery.StringPrefixPredicate) indexQuery;
                String searchTerm = spp.prefix().stringValue();
                Term term = new Term(propertyNames[0], searchTerm);
                query = new LuceneDocumentStructure.PrefixMultiTermsQuery(term);
            } else if (indexQuery.getClass() == PropertyIndexQuery.ExactPredicate.class && indexQuery.valueGroup() == ValueGroup.TEXT) {
                PropertyIndexQuery.ExactPredicate exact = (PropertyIndexQuery.ExactPredicate) indexQuery;
                String searchTerm = ((TextValue) exact.value()).stringValue();
                Term term = new Term(propertyNames[0], searchTerm);
                query = new ConstantScoreQuery(new TermQuery(term));
            } else if (indexQuery.getClass() == PropertyIndexQuery.TextRangePredicate.class) {
                PropertyIndexQuery.TextRangePredicate sp = (PropertyIndexQuery.TextRangePredicate) indexQuery;
                query = newRangeSeekByStringQuery(propertyNames[0], sp.from(), sp.fromInclusive(), sp.to(), sp.toInclusive());
            } else {
                throw new IndexNotApplicableKernelException("A fulltext schema index cannot answer " + indexQuery.type() + " queries on " + indexQuery.valueCategory() + " values.");
            }
            queryBuilder.add(query, BooleanClause.Occur.MUST);
        }
    }
    Query query = queryBuilder.build();
    ValuesIterator itr = searchLucene(query, constraints, context, context.cursorContext(), context.memoryTracker());
    IndexProgressor progressor = new FulltextIndexProgressor(itr, client, constraints);
    client.initialize(index, progressor, queries, constraints, true);
}
Also used : BooleanQuery(org.apache.lucene.search.BooleanQuery) WildcardQuery(org.apache.lucene.search.WildcardQuery) Query(org.apache.lucene.search.Query) ConstantScoreQuery(org.apache.lucene.search.ConstantScoreQuery) WildcardQuery(org.apache.lucene.search.WildcardQuery) TermQuery(org.apache.lucene.search.TermQuery) BooleanQuery(org.apache.lucene.search.BooleanQuery) TermRangeQuery(org.apache.lucene.search.TermRangeQuery) PropertyIndexQuery(org.neo4j.internal.kernel.api.PropertyIndexQuery) PropertyIndexQuery(org.neo4j.internal.kernel.api.PropertyIndexQuery) ConstantScoreQuery(org.apache.lucene.search.ConstantScoreQuery) LuceneDocumentStructure(org.neo4j.kernel.api.impl.schema.LuceneDocumentStructure) TermQuery(org.apache.lucene.search.TermQuery) Term(org.apache.lucene.index.Term) IndexNotApplicableKernelException(org.neo4j.internal.kernel.api.exceptions.schema.IndexNotApplicableKernelException) IndexProgressor(org.neo4j.kernel.api.index.IndexProgressor) ParseException(org.apache.lucene.queryparser.classic.ParseException) ValuesIterator(org.neo4j.kernel.api.impl.index.collector.ValuesIterator)

Aggregations

PropertyIndexQuery (org.neo4j.internal.kernel.api.PropertyIndexQuery)24 ArrayList (java.util.ArrayList)6 KernelTransaction (org.neo4j.kernel.api.KernelTransaction)6 Value (org.neo4j.values.storable.Value)5 Test (org.junit.jupiter.api.Test)4 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)3 EnumSource (org.junit.jupiter.params.provider.EnumSource)3 Pair (org.neo4j.internal.helpers.collection.Pair)3 IndexReadSession (org.neo4j.internal.kernel.api.IndexReadSession)3 TokenRead (org.neo4j.internal.kernel.api.TokenRead)3 IndexNotApplicableKernelException (org.neo4j.internal.kernel.api.exceptions.schema.IndexNotApplicableKernelException)3 ValueIndexEntryUpdate (org.neo4j.storageengine.api.ValueIndexEntryUpdate)3 PointValue (org.neo4j.values.storable.PointValue)3 BooleanQuery (org.apache.lucene.search.BooleanQuery)2 Query (org.apache.lucene.search.Query)2 TermQuery (org.apache.lucene.search.TermQuery)2 Test (org.junit.Test)2 BridgingIndexProgressor (org.neo4j.kernel.api.index.BridgingIndexProgressor)2 SimpleEntityValueClient (org.neo4j.storageengine.api.schema.SimpleEntityValueClient)2 Duration (java.time.Duration)1