Search in sources :

Example 81 with QueryComponent

use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.

the class FDBLuceneQueryTest method delayFetchOnLuceneComplexStringAnd.

@ParameterizedTest
@BooleanSource
public void delayFetchOnLuceneComplexStringAnd(boolean shouldDeferFetch) throws Exception {
    initializeFlat();
    try (FDBRecordContext context = openContext()) {
        openRecordStore(context);
        final QueryComponent filter1 = new LuceneQueryComponent("(the continuance AND grudge)", Lists.newArrayList());
        // Query for full records
        RecordQuery query = RecordQuery.newBuilder().setRecordType(TextIndexTestUtils.SIMPLE_DOC).setFilter(filter1).build();
        setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
        RecordQueryPlan plan = planner.plan(query);
        Matcher<RecordQueryPlan> matcher = indexScan(allOf(indexScanType(IndexScanType.BY_LUCENE_FULL_TEXT), indexName("Complex$text_index"), bounds(hasTupleString("[[(the continuance AND grudge)],[(the continuance AND grudge)]]"))));
        assertThat(plan, matcher);
        List<Long> primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
        assertEquals(ImmutableSet.of(4L), ImmutableSet.copyOf(primaryKeys));
        if (shouldDeferFetch) {
            assertLoadRecord(3, context);
        } else {
            assertLoadRecord(4, context);
        }
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) LuceneQueryComponent(com.apple.foundationdb.record.query.expressions.LuceneQueryComponent) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) LuceneQueryComponent(com.apple.foundationdb.record.query.expressions.LuceneQueryComponent) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) BooleanSource(com.apple.test.BooleanSource)

Example 82 with QueryComponent

use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.

the class FDBLuceneQueryTest method delayFetchOnLuceneFilterWithSort.

@ParameterizedTest
@BooleanSource
public void delayFetchOnLuceneFilterWithSort(boolean shouldDeferFetch) throws Exception {
    initializeFlat();
    try (FDBRecordContext context = openContext()) {
        openRecordStore(context);
        final QueryComponent filter1 = new LuceneQueryComponent("civil blood makes civil hands unclean", Lists.newArrayList("text"), true);
        // Query for full records
        RecordQuery query = RecordQuery.newBuilder().setRecordType(TextIndexTestUtils.SIMPLE_DOC).setFilter(filter1).setSort(field("doc_id")).build();
        setDeferFetchAfterUnionAndIntersection(shouldDeferFetch);
        RecordQueryPlan plan = planner.plan(query);
        List<Long> primaryKeys = recordStore.executeQuery(plan).map(FDBQueriedRecord::getPrimaryKey).map(t -> t.getLong(0)).asList().get();
        assertEquals(ImmutableSet.of(2L, 4L), ImmutableSet.copyOf(primaryKeys));
        if (shouldDeferFetch) {
            assertLoadRecord(5, context);
        } else {
            assertLoadRecord(6, context);
        }
    }
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) LuceneQueryComponent(com.apple.foundationdb.record.query.expressions.LuceneQueryComponent) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) LuceneQueryComponent(com.apple.foundationdb.record.query.expressions.LuceneQueryComponent) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) BooleanSource(com.apple.test.BooleanSource)

Example 83 with QueryComponent

use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.

the class LucenePlanner method getScanForAndLucene.

private LuceneIndexQueryPlan getScanForAndLucene(@Nonnull Index index, @Nullable String parentFieldName, @Nonnull AndComponent filter, @Nullable FilterSatisfiedMask filterMask, final ScanComparisons groupingComparisons) {
    final Iterator<FilterSatisfiedMask> subFilterMasks = filterMask != null ? filterMask.getChildren().iterator() : null;
    final List<QueryComponent> filters = filter.getChildren();
    LuceneIndexQueryPlan combinedComparison = null;
    for (QueryComponent subFilter : filters) {
        final FilterSatisfiedMask childMask = subFilterMasks != null ? subFilterMasks.next() : null;
        LuceneIndexQueryPlan childComparison = getComparisonsForLuceneFilter(index, parentFieldName, subFilter, childMask, groupingComparisons);
        if (childComparison != null && childMask != null) {
            childMask.setSatisfied(true);
            combinedComparison = combinedComparison == null ? childComparison : LuceneIndexQueryPlan.merge(combinedComparison, childComparison, "AND");
        } else if (combinedComparison != null && childComparison == null) {
            combinedComparison = null;
            break;
        }
    }
    if (filterMask != null && filterMask.getUnsatisfiedFilters().isEmpty()) {
        filterMask.setSatisfied(true);
    }
    return combinedComparison;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) LuceneQueryComponent(com.apple.foundationdb.record.query.expressions.LuceneQueryComponent) FilterSatisfiedMask(com.apple.foundationdb.record.query.plan.planning.FilterSatisfiedMask)

Example 84 with QueryComponent

use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.

the class IndexAggregateFunctionCall method extractFieldPaths.

/**
 * Helper method to extract a set of key expressions that are bound through some comparison in the
 * query component passed in.
 * @param queryComponent the query component
 * @param predicate a predicate used for filtering each encountered {@link FieldWithComparison}
 * @return a set of {@link KeyExpression}s where each element is a key expression of a field (i.e. a
 * {@link com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression}) or a simple nesting field
 * (i.e. a {@link com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression}) that is bound
 * through some comparison
 */
@Nonnull
public static Set<KeyExpression> extractFieldPaths(@Nonnull QueryComponent queryComponent, @Nonnull final Predicate<FieldWithComparison> predicate) {
    if (queryComponent instanceof BaseField) {
        final BaseField baseField = (BaseField) queryComponent;
        if (baseField instanceof NestedField) {
            final NestedField nestedField = (NestedField) baseField;
            final Set<KeyExpression> nestedExpressions = extractFieldPaths(nestedField.getChild(), predicate);
            return nestedExpressions.stream().map(nestedExpression -> Key.Expressions.field(nestedField.getFieldName()).nest(nestedExpression)).collect(ImmutableSet.toImmutableSet());
        }
        if (baseField instanceof FieldWithComparison) {
            final FieldWithComparison fieldWithComparison = (FieldWithComparison) baseField;
            if (predicate.test(fieldWithComparison)) {
                return ImmutableSet.of(Key.Expressions.field(fieldWithComparison.getFieldName()));
            }
        }
        return ImmutableSet.of();
    } else if (queryComponent instanceof AndComponent) {
        final Set<KeyExpression> boundFields = Sets.newHashSet();
        final AndComponent andComponent = (AndComponent) queryComponent;
        andComponent.getChildren().forEach(child -> boundFields.addAll(extractEqualityBoundFields(child)));
        return boundFields;
    }
    return ImmutableSet.of();
}
Also used : NestedField(com.apple.foundationdb.record.query.expressions.NestedField) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison) Iterables(com.google.common.collect.Iterables) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ImmutableSet(com.google.common.collect.ImmutableSet) Predicate(java.util.function.Predicate) Set(java.util.Set) EnumeratingIterable(com.apple.foundationdb.record.query.combinatorics.EnumeratingIterable) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) Sets(com.google.common.collect.Sets) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) List(java.util.List) NestedField(com.apple.foundationdb.record.query.expressions.NestedField) Stream(java.util.stream.Stream) BaseField(com.apple.foundationdb.record.query.expressions.BaseField) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) StreamSupport(java.util.stream.StreamSupport) API(com.apple.foundationdb.annotation.API) Objects(com.google.common.base.Objects) Nonnull(javax.annotation.Nonnull) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) TopologicalSort(com.apple.foundationdb.record.query.combinatorics.TopologicalSort) Nullable(javax.annotation.Nullable) BaseField(com.apple.foundationdb.record.query.expressions.BaseField) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison) Nonnull(javax.annotation.Nonnull)

Example 85 with QueryComponent

use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.

the class RecordQueryPlanner method planOneOfThemWithComponent.

@Nullable
private ScoredPlan planOneOfThemWithComponent(@Nonnull CandidateScan candidateScan, @Nonnull KeyExpression indexExpr, @Nonnull OneOfThemWithComponent filter, @Nullable KeyExpression sort) {
    if (indexExpr instanceof FieldKeyExpression) {
        return null;
    } else if (indexExpr instanceof ThenKeyExpression) {
        ThenKeyExpression then = (ThenKeyExpression) indexExpr;
        return planOneOfThemWithComponent(candidateScan, then.getChildren().get(0), filter, sort);
    } else if (indexExpr instanceof NestingKeyExpression) {
        NestingKeyExpression indexNesting = (NestingKeyExpression) indexExpr;
        ScoredPlan plan = null;
        if (sort == null) {
            plan = planNesting(candidateScan, indexNesting, filter, null);
        } else if (sort instanceof FieldKeyExpression) {
            plan = null;
        } else if (sort instanceof ThenKeyExpression) {
            plan = null;
        } else if (sort instanceof NestingKeyExpression) {
            NestingKeyExpression sortNesting = (NestingKeyExpression) sort;
            plan = planNesting(candidateScan, indexNesting, filter, sortNesting);
        }
        if (plan != null) {
            List<QueryComponent> unsatisfied;
            if (!plan.unsatisfiedFilters.isEmpty()) {
                unsatisfied = Collections.singletonList(filter);
            } else {
                unsatisfied = Collections.emptyList();
            }
            // Right now it marks the whole nesting as unsatisfied, in theory there could be plans that handle that
            plan = new ScoredPlan(plan.score, plan.plan, unsatisfied, true);
        }
        return plan;
    }
    return null;
}
Also used : ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) Nullable(javax.annotation.Nullable)

Aggregations

QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)96 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)58 RecordQuery (com.apple.foundationdb.record.query.RecordQuery)44 Test (org.junit.jupiter.api.Test)41 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)37 ArrayList (java.util.ArrayList)30 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)29 FDBQueriedRecord (com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord)25 Index (com.apple.foundationdb.record.metadata.Index)24 Nonnull (javax.annotation.Nonnull)23 Comparisons (com.apple.foundationdb.record.query.expressions.Comparisons)22 Message (com.google.protobuf.Message)22 Query (com.apple.foundationdb.record.query.expressions.Query)20 RecordQueryPlanner (com.apple.foundationdb.record.query.plan.RecordQueryPlanner)20 List (java.util.List)20 Collections (java.util.Collections)19 Nullable (javax.annotation.Nullable)18 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)18 PlanHashable (com.apple.foundationdb.record.PlanHashable)17 Expressions.field (com.apple.foundationdb.record.metadata.Key.Expressions.field)17