Search in sources :

Example 21 with PropertyIndexQuery

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

the class GenericNativeIndexReader method query.

@Override
public void query(QueryContext context, IndexProgressor.EntityValueClient client, IndexQueryConstraints constraints, PropertyIndexQuery... query) {
    PropertyIndexQuery.GeometryRangePredicate geometryRangePredicate = getGeometryRangePredicateIfAny(query);
    if (geometryRangePredicate != null) {
        validateQuery(constraints, query);
        try {
            // If there's a GeometryRangeQuery among the predicates then this query changes from a straight-forward: build from/to and seek...
            // into a query that is split into multiple sub-queries. Predicates both before and after will have to be accompanied each sub-query.
            BridgingIndexProgressor multiProgressor = new BridgingIndexProgressor(client, descriptor.schema().getPropertyIds());
            client.initialize(descriptor, multiProgressor, query, constraints, false);
            double[] from = geometryRangePredicate.from() == null ? null : geometryRangePredicate.from().coordinate();
            double[] to = geometryRangePredicate.to() == null ? null : geometryRangePredicate.to().coordinate();
            CoordinateReferenceSystem crs = geometryRangePredicate.crs();
            SpaceFillingCurve curve = spaceFillingCurveSettings.forCrs(crs);
            List<SpaceFillingCurve.LongRange> ranges = curve.getTilesIntersectingEnvelope(from, to, configuration);
            for (SpaceFillingCurve.LongRange range : ranges) {
                // Here's a sub-query that we'll have to do for this geometry range. Build this query from all predicates
                // and when getting to the geometry range predicate that sparked these sub-query chenanigans, swap in this sub-query in its place.
                GenericKey treeKeyFrom = layout.newKey();
                GenericKey treeKeyTo = layout.newKey();
                initializeFromToKeys(treeKeyFrom, treeKeyTo);
                boolean needFiltering = initializeRangeForGeometrySubQuery(treeKeyFrom, treeKeyTo, query, crs, range);
                startSeekForInitializedRange(multiProgressor, treeKeyFrom, treeKeyTo, query, constraints, needFiltering, context.cursorContext());
            }
        } catch (IllegalArgumentException e) {
            // Invalid query ranges will cause this state (eg. min>max)
            client.initialize(descriptor, IndexProgressor.EMPTY, query, constraints, false);
        }
    } else {
        super.query(context, client, constraints, query);
    }
}
Also used : PropertyIndexQuery(org.neo4j.internal.kernel.api.PropertyIndexQuery) SpaceFillingCurve(org.neo4j.gis.spatial.index.curves.SpaceFillingCurve) CoordinateReferenceSystem(org.neo4j.values.storable.CoordinateReferenceSystem) BridgingIndexProgressor(org.neo4j.kernel.api.index.BridgingIndexProgressor)

Example 22 with PropertyIndexQuery

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

the class QueryValidator method validateCompositeQuery.

/**
 * Composite queries are somewhat restricted in what combination of predicates
 * that are allowed together and in what order.
 *
 * 1. Decreasing precision.
 * Composite queries must have decreasing precision on the slots, meaning
 * for example that a range predicate can not be followed by an exact
 * predicate.
 * The reason for this is that because the index is sorted in lexicographic
 * order with regards to the slots a predicate with increasing precision
 * does not narrow down the search space in the index.
 * It could of course be implemented by scanning the search space and do
 * post filtering, but this is not how the implementation currently works.
 *
 * 2. Contains and suffix.
 * Contains or suffix queries are not allowed in composite queries at all.
 * This is because they both demand a full scan of the search space, just like
 * "exist", and the post filtering of the result. This is how it works in the
 * non-composite case but it has not yet been implemented for the composite case.
 *
 * @param predicates The query for which we want to check the composite validity.
 */
static void validateCompositeQuery(PropertyIndexQuery[] predicates) {
    PropertyIndexQuery prev = null;
    for (PropertyIndexQuery current : predicates) {
        String illegalQueryMessage = "Tried to query index with illegal composite query.";
        if (current instanceof PropertyIndexQuery.StringContainsPredicate || current instanceof PropertyIndexQuery.StringSuffixPredicate) {
            if (predicates.length > 1) {
                throw new IllegalArgumentException(format("%s Suffix or contains predicate are not allowed in composite query. Query was: %s ", illegalQueryMessage, Arrays.toString(predicates)));
            }
        }
        if (prev instanceof PropertyIndexQuery.RangePredicate || prev instanceof PropertyIndexQuery.StringPrefixPredicate || prev instanceof PropertyIndexQuery.ExistsPredicate) {
            if (!(current instanceof PropertyIndexQuery.ExistsPredicate)) {
                throw new IllegalArgumentException(format("%s Composite query must have decreasing precision. Query was: %s ", illegalQueryMessage, Arrays.toString(predicates)));
            }
        }
        prev = current;
    }
}
Also used : PropertyIndexQuery(org.neo4j.internal.kernel.api.PropertyIndexQuery)

Example 23 with PropertyIndexQuery

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

the class NativeIndexAccessorTests method mustHandleNestedQueries.

private void mustHandleNestedQueries(ValueIndexEntryUpdate<IndexDescriptor>[] updates) throws IndexEntryConflictException, IndexNotApplicableKernelException {
    processAll(updates);
    ValueCreatorUtil.sort(updates);
    // when
    var reader = accessor.newValueReader();
    PropertyIndexQuery outerQuery = ValueCreatorUtil.rangeQuery(valueOf(updates[2]), true, valueOf(updates[3]), true);
    PropertyIndexQuery innerQuery = ValueCreatorUtil.rangeQuery(valueOf(updates[0]), true, valueOf(updates[1]), true);
    long[] expectedOuter = { entityIdOf(updates[2]), entityIdOf(updates[3]) };
    long[] expectedInner = { entityIdOf(updates[0]), entityIdOf(updates[1]) };
    Collection<Long> outerResult;
    try (NodeValueIterator outerIter = query(reader, outerQuery)) {
        outerResult = new ArrayList<>();
        while (outerIter.hasNext()) {
            outerResult.add(outerIter.next());
            try (NodeValueIterator innerIter = query(reader, innerQuery)) {
                assertEntityIdHits(expectedInner, innerIter);
            }
        }
    }
    assertEntityIdHits(expectedOuter, outerResult);
}
Also used : PropertyIndexQuery(org.neo4j.internal.kernel.api.PropertyIndexQuery)

Example 24 with PropertyIndexQuery

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

the class FusionIndexReaderTest method mustSelectLuceneForExactPredicateWithStringValue.

@Test
void mustSelectLuceneForExactPredicateWithStringValue() throws Exception {
    // given
    for (Object value : FusionIndexTestHelp.valuesSupportedByLucene()) {
        PropertyIndexQuery indexQuery = PropertyIndexQuery.exact(PROP_KEY, value);
        // then
        verifyQueryWithCorrectReader(readers.get(LUCENE), indexQuery);
    }
}
Also used : PropertyIndexQuery(org.neo4j.internal.kernel.api.PropertyIndexQuery) Test(org.junit.jupiter.api.Test)

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