Search in sources :

Example 1 with FullTextExpression

use of org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression in project jackrabbit-oak by apache.

the class AggregateIndex method getPlans.

@Override
public List<IndexPlan> getPlans(Filter filter, List<OrderEntry> sortOrder, NodeState rootState) {
    if (baseIndex == null) {
        return Collections.emptyList();
    }
    FullTextExpression e = filter.getFullTextConstraint();
    if (getNodeAggregator() == null || e == null) {
        // no aggregation: path-though
        return baseIndex.getPlans(filter, sortOrder, rootState);
    }
    if (!hasCompositeExpression(e)) {
        // path-though, but without node type restriction
        return baseIndex.getPlans(newAggregationFilter(filter, null), sortOrder, rootState);
    }
    AggregateIndexPlan plan = new AggregateIndexPlan(filter);
    collectCombinedPlan(e, filter, sortOrder, rootState, plan, "");
    if (plan.containsPathWithoutPlan()) {
        // the full-text index didn't return a plan
        LOG.debug("Full-text index without plan: " + e);
        return Collections.emptyList();
    }
    return Collections.singletonList((IndexPlan) plan);
}
Also used : FullTextExpression(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression)

Example 2 with FullTextExpression

use of org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression in project jackrabbit-oak by apache.

the class AggregateIndex method flatten.

private Cursor flatten(FullTextExpression constraint, final AggregateIndexPlan plan, final Filter filter, final NodeState state, final String path) {
    if (constraint == null) {
        return null;
    }
    final AtomicReference<Cursor> result = new AtomicReference<Cursor>();
    constraint.accept(new FullTextVisitor() {

        @Override
        public boolean visit(FullTextContains contains) {
            return contains.getBase().accept(this);
        }

        @Override
        public boolean visit(FullTextTerm term) {
            IndexPlan p = plan.getPlan(path);
            result.set(newAggregationCursor(p, state));
            return true;
        }

        @Override
        public boolean visit(FullTextAnd and) {
            Iterator<FullTextExpression> iterator = and.list.iterator();
            int index = 0;
            Cursor c = flatten(iterator.next(), plan, filter, state, path + " and(" + index + ")");
            while (iterator.hasNext()) {
                index++;
                FullTextExpression input = iterator.next();
                Cursor newC = flatten(input, plan, filter, state, path + " and(" + index + ")");
                c = Cursors.newIntersectionCursor(c, newC, filter.getQueryLimits());
            }
            result.set(c);
            return true;
        }

        @Override
        public boolean visit(FullTextOr or) {
            final int[] index = new int[1];
            List<Cursor> cursors = Lists.transform(or.list, new Function<FullTextExpression, Cursor>() {

                @Override
                public Cursor apply(FullTextExpression input) {
                    return flatten(input, plan, filter, state, path + " or(" + index[0]++ + ")");
                }
            });
            result.set(Cursors.newConcatCursor(cursors, filter.getQueryLimits()));
            return true;
        }
    });
    return result.get();
}
Also used : FullTextOr(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextOr) FullTextContains(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextContains) AtomicReference(java.util.concurrent.atomic.AtomicReference) Cursor(org.apache.jackrabbit.oak.spi.query.Cursor) Function(com.google.common.base.Function) FullTextVisitor(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextVisitor) FullTextTerm(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextTerm) FullTextAnd(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextAnd) Iterator(java.util.Iterator) FullTextExpression(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression) List(java.util.List)

Example 3 with FullTextExpression

use of org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression in project jackrabbit-oak by apache.

the class LucenePropertyIndex method getLuceneRequest.

/**
 * Get the Lucene query for the given filter.
 *
 * @param plan index plan containing filter details
 * @param reader the Lucene reader
 * @return the Lucene query
 */
private static LuceneRequestFacade getLuceneRequest(IndexPlan plan, IndexAugmentorFactory augmentorFactory, IndexReader reader) {
    FulltextQueryTermsProvider augmentor = getIndexAgumentor(plan, augmentorFactory);
    List<Query> qs = new ArrayList<Query>();
    Filter filter = plan.getFilter();
    FullTextExpression ft = filter.getFullTextConstraint();
    PlanResult planResult = getPlanResult(plan);
    IndexDefinition defn = planResult.indexDefinition;
    Analyzer analyzer = defn.getAnalyzer();
    if (ft == null) {
    // there might be no full-text constraint
    // when using the LowCostLuceneIndexProvider
    // which is used for testing
    } else {
        qs.add(getFullTextQuery(plan, ft, analyzer, augmentor));
    }
    // Check if native function is supported
    PropertyRestriction pr = null;
    if (defn.hasFunctionDefined()) {
        pr = filter.getPropertyRestriction(defn.getFunctionName());
    }
    if (pr != null) {
        String query = String.valueOf(pr.first.getValue(pr.first.getType()));
        QueryParser queryParser = new QueryParser(VERSION, "", analyzer);
        if (query.startsWith("mlt?")) {
            String mltQueryString = query.replace("mlt?", "");
            if (reader != null) {
                Query moreLikeThis = MoreLikeThisHelper.getMoreLikeThis(reader, analyzer, mltQueryString);
                if (moreLikeThis != null) {
                    qs.add(moreLikeThis);
                }
            }
        } else if (query.startsWith("spellcheck?")) {
            String spellcheckQueryString = query.replace("spellcheck?", "");
            if (reader != null) {
                return new LuceneRequestFacade<SpellcheckHelper.SpellcheckQuery>(SpellcheckHelper.getSpellcheckQuery(spellcheckQueryString, reader));
            }
        } else if (query.startsWith("suggest?")) {
            String suggestQueryString = query.replace("suggest?", "");
            if (reader != null) {
                return new LuceneRequestFacade<SuggestHelper.SuggestQuery>(SuggestHelper.getSuggestQuery(suggestQueryString));
            }
        } else {
            try {
                qs.add(queryParser.parse(query));
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
    } else if (planResult.evaluateNonFullTextConstraints()) {
        addNonFullTextConstraints(qs, plan, reader);
    }
    if (qs.size() == 0 && plan.getSortOrder() != null) {
        // This case indicates that query just had order by and no
        // property restriction defined. In this case property
        // existence queries for each sort entry
        List<OrderEntry> orders = removeNativeSort(plan.getSortOrder());
        for (int i = 0; i < orders.size(); i++) {
            OrderEntry oe = orders.get(i);
            PropertyDefinition pd = planResult.getOrderedProperty(i);
            PropertyRestriction orderRest = new PropertyRestriction();
            orderRest.propertyName = oe.getPropertyName();
            Query q = createQuery(oe.getPropertyName(), orderRest, pd);
            if (q != null) {
                qs.add(q);
            }
        }
    }
    if (qs.size() == 0) {
        if (reader == null) {
            // just return match all queries
            return new LuceneRequestFacade<Query>(new MatchAllDocsQuery());
        }
        // be returned (if the index definition has a single rule)
        if (planResult.evaluateNodeTypeRestriction()) {
            return new LuceneRequestFacade<Query>(new MatchAllDocsQuery());
        }
        throw new IllegalStateException("No query created for filter " + filter);
    }
    return performAdditionalWraps(qs);
}
Also used : PropertyRestriction(org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction) PlanResult(org.apache.jackrabbit.oak.plugins.index.lucene.IndexPlanner.PlanResult) Query(org.apache.lucene.search.Query) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) WildcardQuery(org.apache.lucene.search.WildcardQuery) NumericRangeQuery(org.apache.lucene.search.NumericRangeQuery) CustomScoreQuery(org.apache.lucene.queries.CustomScoreQuery) PrefixQuery(org.apache.lucene.search.PrefixQuery) TermQuery(org.apache.lucene.search.TermQuery) BooleanQuery(org.apache.lucene.search.BooleanQuery) TermRangeQuery(org.apache.lucene.search.TermRangeQuery) SuggestHelper(org.apache.jackrabbit.oak.plugins.index.lucene.util.SuggestHelper) ArrayList(java.util.ArrayList) FulltextQueryTermsProvider(org.apache.jackrabbit.oak.plugins.index.lucene.spi.FulltextQueryTermsProvider) Analyzer(org.apache.lucene.analysis.Analyzer) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) StandardQueryParser(org.apache.lucene.queryparser.flexible.standard.StandardQueryParser) QueryParser(org.apache.lucene.queryparser.classic.QueryParser) Filter(org.apache.jackrabbit.oak.spi.query.Filter) FullTextExpression(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression) ParseException(org.apache.lucene.queryparser.classic.ParseException)

Example 4 with FullTextExpression

use of org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression in project jackrabbit-oak by apache.

the class LucenePropertyIndex method getFullTextQuery.

static Query getFullTextQuery(final IndexPlan plan, FullTextExpression ft, final Analyzer analyzer, final FulltextQueryTermsProvider augmentor) {
    final PlanResult pr = getPlanResult(plan);
    // a reference to the query, so it can be set in the visitor
    // (a "non-local return")
    final AtomicReference<Query> result = new AtomicReference<Query>();
    ft.accept(new FullTextVisitor() {

        @Override
        public boolean visit(FullTextContains contains) {
            visitTerm(contains.getPropertyName(), contains.getRawText(), null, contains.isNot());
            return true;
        }

        @Override
        public boolean visit(FullTextOr or) {
            BooleanQuery q = new BooleanQuery();
            for (FullTextExpression e : or.list) {
                Query x = getFullTextQuery(plan, e, analyzer, augmentor);
                q.add(x, SHOULD);
            }
            result.set(q);
            return true;
        }

        @Override
        public boolean visit(FullTextAnd and) {
            BooleanQuery q = new BooleanQuery();
            for (FullTextExpression e : and.list) {
                Query x = getFullTextQuery(plan, e, analyzer, augmentor);
                /* Only unwrap the clause if MUST_NOT(x) */
                boolean hasMustNot = false;
                if (x instanceof BooleanQuery) {
                    BooleanQuery bq = (BooleanQuery) x;
                    if ((bq.getClauses().length == 1) && (bq.getClauses()[0].getOccur() == BooleanClause.Occur.MUST_NOT)) {
                        hasMustNot = true;
                        q.add(bq.getClauses()[0]);
                    }
                }
                if (!hasMustNot) {
                    q.add(x, MUST);
                }
            }
            result.set(q);
            return true;
        }

        @Override
        public boolean visit(FullTextTerm term) {
            return visitTerm(term.getPropertyName(), term.getText(), term.getBoost(), term.isNot());
        }

        private boolean visitTerm(String propertyName, String text, String boost, boolean not) {
            String p = getLuceneFieldName(propertyName, pr);
            Query q = tokenToQuery(text, p, pr, analyzer, augmentor);
            if (q == null) {
                return false;
            }
            if (boost != null) {
                q.setBoost(Float.parseFloat(boost));
            }
            if (not) {
                BooleanQuery bq = new BooleanQuery();
                bq.add(q, MUST_NOT);
                result.set(bq);
            } else {
                result.set(q);
            }
            return true;
        }
    });
    return result.get();
}
Also used : BooleanQuery(org.apache.lucene.search.BooleanQuery) PlanResult(org.apache.jackrabbit.oak.plugins.index.lucene.IndexPlanner.PlanResult) Query(org.apache.lucene.search.Query) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) WildcardQuery(org.apache.lucene.search.WildcardQuery) NumericRangeQuery(org.apache.lucene.search.NumericRangeQuery) CustomScoreQuery(org.apache.lucene.queries.CustomScoreQuery) PrefixQuery(org.apache.lucene.search.PrefixQuery) TermQuery(org.apache.lucene.search.TermQuery) BooleanQuery(org.apache.lucene.search.BooleanQuery) TermRangeQuery(org.apache.lucene.search.TermRangeQuery) FullTextOr(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextOr) FullTextContains(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextContains) AtomicReference(java.util.concurrent.atomic.AtomicReference) FullTextVisitor(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextVisitor) FullTextTerm(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextTerm) FullTextAnd(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextAnd) FullTextExpression(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression)

Example 5 with FullTextExpression

use of org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression in project jackrabbit-oak by apache.

the class LucenePropertyIndex method getPlanDescription.

@Override
public String getPlanDescription(IndexPlan plan, NodeState root) {
    Filter filter = plan.getFilter();
    IndexNode index = tracker.acquireIndexNode(getPlanResult(plan).indexPath);
    checkState(index != null, "The Lucene index is not available");
    try {
        FullTextExpression ft = filter.getFullTextConstraint();
        StringBuilder sb = new StringBuilder("lucene:");
        String path = getPlanResult(plan).indexPath;
        sb.append(getIndexName(plan)).append("(").append(path).append(") ");
        sb.append(getLuceneRequest(plan, augmentorFactory, null));
        if (plan.getSortOrder() != null && !plan.getSortOrder().isEmpty()) {
            sb.append(" ordering:").append(plan.getSortOrder());
        }
        if (ft != null) {
            sb.append(" ft:(").append(ft).append(")");
        }
        addSyncIndexPlan(plan, sb);
        return sb.toString();
    } finally {
        index.release();
    }
}
Also used : Filter(org.apache.jackrabbit.oak.spi.query.Filter) FullTextExpression(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression)

Aggregations

FullTextExpression (org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression)21 Filter (org.apache.jackrabbit.oak.spi.query.Filter)7 FullTextAnd (org.apache.jackrabbit.oak.spi.query.fulltext.FullTextAnd)6 FullTextContains (org.apache.jackrabbit.oak.spi.query.fulltext.FullTextContains)6 FullTextTerm (org.apache.jackrabbit.oak.spi.query.fulltext.FullTextTerm)5 BooleanQuery (org.apache.lucene.search.BooleanQuery)5 MatchAllDocsQuery (org.apache.lucene.search.MatchAllDocsQuery)5 PrefixQuery (org.apache.lucene.search.PrefixQuery)5 Query (org.apache.lucene.search.Query)5 TermQuery (org.apache.lucene.search.TermQuery)5 TermRangeQuery (org.apache.lucene.search.TermRangeQuery)5 WildcardQuery (org.apache.lucene.search.WildcardQuery)5 Test (org.junit.Test)5 PropertyRestriction (org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction)4 FullTextOr (org.apache.jackrabbit.oak.spi.query.fulltext.FullTextOr)4 FullTextVisitor (org.apache.jackrabbit.oak.spi.query.fulltext.FullTextVisitor)4 ArrayList (java.util.ArrayList)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 NodeBuilder (org.apache.jackrabbit.oak.spi.state.NodeBuilder)3 PhraseQuery (org.apache.lucene.search.PhraseQuery)3