Search in sources :

Example 11 with PropertyRestriction

use of org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction in project jackrabbit-oak by apache.

the class LuceneIndex method addNonFullTextConstraints.

private static void addNonFullTextConstraints(List<Query> qs, Filter filter, IndexReader reader, Analyzer analyzer, IndexDefinition indexDefinition) {
    if (!filter.matchesAllTypes()) {
        addNodeTypeConstraints(qs, filter);
    }
    String path = filter.getPath();
    switch(filter.getPathRestriction()) {
        case ALL_CHILDREN:
            if (USE_PATH_RESTRICTION) {
                if ("/".equals(path)) {
                    break;
                }
                if (!path.endsWith("/")) {
                    path += "/";
                }
                qs.add(new PrefixQuery(newPathTerm(path)));
            }
            break;
        case DIRECT_CHILDREN:
            if (USE_PATH_RESTRICTION) {
                if (!path.endsWith("/")) {
                    path += "/";
                }
                qs.add(new PrefixQuery(newPathTerm(path)));
            }
            break;
        case EXACT:
            qs.add(new TermQuery(newPathTerm(path)));
            break;
        case PARENT:
            if (denotesRoot(path)) {
                // there's no parent of the root node
                // we add a path that can not possibly occur because there
                // is no way to say "match no documents" in Lucene
                qs.add(new TermQuery(new Term(FieldNames.PATH, "///")));
            } else {
                qs.add(new TermQuery(newPathTerm(getParentPath(path))));
            }
            break;
        case NO_RESTRICTION:
            break;
    }
    // Fulltext index definition used by LuceneIndex only works with old format
    // which is not nodeType based. So just use the nt:base index
    IndexingRule rule = indexDefinition.getApplicableIndexingRule(JcrConstants.NT_BASE);
    for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
        if (pr.first == null && pr.last == null) {
            // queries (OAK-1208)
            continue;
        }
        // check excluded properties and types
        if (isExcludedProperty(pr, rule)) {
            continue;
        }
        String name = pr.propertyName;
        if (QueryConstants.REP_EXCERPT.equals(name) || QueryConstants.OAK_SCORE_EXPLANATION.equals(name) || QueryConstants.REP_FACET.equals(name)) {
            continue;
        }
        if (JCR_PRIMARYTYPE.equals(name)) {
            continue;
        }
        if (QueryConstants.RESTRICTION_LOCAL_NAME.equals(name)) {
            continue;
        }
        if (skipTokenization(name)) {
            qs.add(new TermQuery(new Term(name, pr.first.getValue(STRING))));
            continue;
        }
        String first = null;
        String last = null;
        boolean isLike = pr.isLike;
        // TODO what to do with escaped tokens?
        if (pr.first != null) {
            first = pr.first.getValue(STRING);
            first = first.replace("\\", "");
        }
        if (pr.last != null) {
            last = pr.last.getValue(STRING);
            last = last.replace("\\", "");
        }
        if (isLike) {
            first = first.replace('%', WildcardQuery.WILDCARD_STRING);
            first = first.replace('_', WildcardQuery.WILDCARD_CHAR);
            int indexOfWS = first.indexOf(WildcardQuery.WILDCARD_STRING);
            int indexOfWC = first.indexOf(WildcardQuery.WILDCARD_CHAR);
            int len = first.length();
            if (indexOfWS == len || indexOfWC == len) {
                // remove trailing "*" for prefixquery
                first = first.substring(0, first.length() - 1);
                if (JCR_PATH.equals(name)) {
                    qs.add(new PrefixQuery(newPathTerm(first)));
                } else {
                    qs.add(new PrefixQuery(new Term(name, first)));
                }
            } else {
                if (JCR_PATH.equals(name)) {
                    qs.add(new WildcardQuery(newPathTerm(first)));
                } else {
                    qs.add(new WildcardQuery(new Term(name, first)));
                }
            }
            continue;
        }
        if (first != null && first.equals(last) && pr.firstIncluding && pr.lastIncluding) {
            if (JCR_PATH.equals(name)) {
                qs.add(new TermQuery(newPathTerm(first)));
            } else {
                if ("*".equals(name)) {
                    addReferenceConstraint(first, qs, reader);
                } else {
                    for (String t : tokenize(first, analyzer)) {
                        qs.add(new TermQuery(new Term(name, t)));
                    }
                }
            }
            continue;
        }
        first = tokenizeAndPoll(first, analyzer);
        last = tokenizeAndPoll(last, analyzer);
        qs.add(TermRangeQuery.newStringRange(name, first, last, pr.firstIncluding, pr.lastIncluding));
    }
}
Also used : TermQuery(org.apache.lucene.search.TermQuery) PropertyRestriction(org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction) WildcardQuery(org.apache.lucene.search.WildcardQuery) IndexingRule(org.apache.jackrabbit.oak.plugins.index.lucene.IndexDefinition.IndexingRule) PrefixQuery(org.apache.lucene.search.PrefixQuery) Term(org.apache.lucene.index.Term) FullTextTerm(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextTerm) TermFactory.newPathTerm(org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newPathTerm) TermFactory.newFulltextTerm(org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newFulltextTerm)

Example 12 with PropertyRestriction

use of org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction in project jackrabbit-oak by apache.

the class LuceneIndex method getLuceneRequest.

/**
 * Get the Lucene query for the given filter.
 *
 * @param filter the filter, including full-text constraint
 * @param reader the Lucene reader
 * @param nonFullTextConstraints whether non-full-text constraints (such a
 *            path, node type, and so on) should be added to the Lucene
 *            query
 * @param indexDefinition nodestate that contains the index definition
 * @return the Lucene query
 */
private static LuceneRequestFacade getLuceneRequest(Filter filter, IndexReader reader, boolean nonFullTextConstraints, IndexDefinition indexDefinition) {
    List<Query> qs = new ArrayList<Query>();
    Analyzer analyzer = indexDefinition.getAnalyzer();
    FullTextExpression ft = filter.getFullTextConstraint();
    if (ft == null) {
    // there might be no full-text constraint
    // when using the LowCostLuceneIndexProvider
    // which is used for testing
    } else {
        qs.add(getFullTextQuery(ft, analyzer, reader));
    }
    PropertyRestriction pr = filter.getPropertyRestriction(NATIVE_QUERY_FUNCTION);
    if (pr != null) {
        String query = String.valueOf(pr.first.getValue(pr.first.getType()));
        QueryParser queryParser = new QueryParser(VERSION, "", indexDefinition.getAnalyzer());
        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);
                }
            }
        }
        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 (nonFullTextConstraints) {
        addNonFullTextConstraints(qs, filter, reader, analyzer, indexDefinition);
    }
    if (qs.size() == 0) {
        return new LuceneRequestFacade<Query>(new MatchAllDocsQuery());
    }
    return LucenePropertyIndex.performAdditionalWraps(qs);
}
Also used : PropertyRestriction(org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction) Query(org.apache.lucene.search.Query) PhraseQuery(org.apache.lucene.search.PhraseQuery) PrefixQuery(org.apache.lucene.search.PrefixQuery) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) WildcardQuery(org.apache.lucene.search.WildcardQuery) TermQuery(org.apache.lucene.search.TermQuery) BooleanQuery(org.apache.lucene.search.BooleanQuery) TermRangeQuery(org.apache.lucene.search.TermRangeQuery) ArrayList(java.util.ArrayList) Analyzer(org.apache.lucene.analysis.Analyzer) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) QueryParser(org.apache.lucene.queryparser.classic.QueryParser) FullTextExpression(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression) SpellcheckHelper(org.apache.jackrabbit.oak.plugins.index.lucene.util.SpellcheckHelper) ParseException(org.apache.lucene.queryparser.classic.ParseException)

Example 13 with PropertyRestriction

use of org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction in project jackrabbit-oak by apache.

the class LucenePropertyIndex method query.

@Override
public Cursor query(final IndexPlan plan, NodeState rootState) {
    final Filter filter = plan.getFilter();
    final Sort sort = getSort(plan);
    final PlanResult pr = getPlanResult(plan);
    QueryLimits settings = filter.getQueryLimits();
    Iterator<LuceneResultRow> itr = new AbstractIterator<LuceneResultRow>() {

        private final Deque<LuceneResultRow> queue = Queues.newArrayDeque();

        private final Set<String> seenPaths = Sets.newHashSet();

        private ScoreDoc lastDoc;

        private int nextBatchSize = LUCENE_QUERY_BATCH_SIZE;

        private boolean noDocs = false;

        private IndexSearcher indexSearcher;

        private int indexNodeId = -1;

        @Override
        protected LuceneResultRow computeNext() {
            while (!queue.isEmpty() || loadDocs()) {
                return queue.remove();
            }
            releaseSearcher();
            return endOfData();
        }

        private LuceneResultRow convertToRow(ScoreDoc doc, IndexSearcher searcher, Map<String, String> excerpts, Facets facets, String explanation) throws IOException {
            IndexReader reader = searcher.getIndexReader();
            // TODO Look into usage of field cache for retrieving the path
            // instead of reading via reader if no of docs in index are limited
            PathStoredFieldVisitor visitor = new PathStoredFieldVisitor();
            reader.document(doc.doc, visitor);
            String path = visitor.getPath();
            if (path != null) {
                if ("".equals(path)) {
                    path = "/";
                }
                if (pr.isPathTransformed()) {
                    String originalPath = path;
                    path = pr.transformPath(path);
                    if (path == null) {
                        LOG.trace("Ignoring path {} : Transformation returned null", originalPath);
                        return null;
                    }
                    // avoid duplicate entries
                    if (seenPaths.contains(path)) {
                        LOG.trace("Ignoring path {} : Duplicate post transformation", originalPath);
                        return null;
                    }
                    seenPaths.add(path);
                }
                boolean shouldIncludeForHierarchy = shouldInclude(path, plan);
                LOG.trace("Matched path {}; shouldIncludeForHierarchy: {}", path, shouldIncludeForHierarchy);
                return shouldIncludeForHierarchy ? new LuceneResultRow(path, doc.score, excerpts, facets, explanation) : null;
            }
            return null;
        }

        /**
         * Loads the lucene documents in batches
         * @return true if any document is loaded
         */
        private boolean loadDocs() {
            if (noDocs) {
                return false;
            }
            ScoreDoc lastDocToRecord = null;
            final IndexNode indexNode = acquireIndexNode(plan);
            checkState(indexNode != null);
            try {
                IndexSearcher searcher = getCurrentSearcher(indexNode);
                LuceneRequestFacade luceneRequestFacade = getLuceneRequest(plan, augmentorFactory, searcher.getIndexReader());
                if (luceneRequestFacade.getLuceneRequest() instanceof Query) {
                    Query query = (Query) luceneRequestFacade.getLuceneRequest();
                    CustomScoreQuery customScoreQuery = getCustomScoreQuery(plan, query);
                    if (customScoreQuery != null) {
                        query = customScoreQuery;
                    }
                    TopDocs docs;
                    long start = PERF_LOGGER.start();
                    while (true) {
                        if (lastDoc != null) {
                            LOG.debug("loading the next {} entries for query {}", nextBatchSize, query);
                            if (sort == null) {
                                docs = searcher.searchAfter(lastDoc, query, nextBatchSize);
                            } else {
                                docs = searcher.searchAfter(lastDoc, query, nextBatchSize, sort);
                            }
                        } else {
                            LOG.debug("loading the first {} entries for query {}", nextBatchSize, query);
                            if (sort == null) {
                                docs = searcher.search(query, nextBatchSize);
                            } else {
                                docs = searcher.search(query, nextBatchSize, sort);
                            }
                        }
                        PERF_LOGGER.end(start, -1, "{} ...", docs.scoreDocs.length);
                        nextBatchSize = (int) Math.min(nextBatchSize * 2L, 100000);
                        long f = PERF_LOGGER.start();
                        Facets facets = FacetHelper.getFacets(searcher, query, docs, plan, indexNode.getDefinition().isSecureFacets());
                        PERF_LOGGER.end(f, -1, "facets retrieved");
                        Set<String> excerptFields = Sets.newHashSet();
                        for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
                            if (QueryConstants.REP_EXCERPT.equals(pr.propertyName)) {
                                String value = pr.first.getValue(Type.STRING);
                                excerptFields.add(value);
                            }
                        }
                        boolean addExcerpt = excerptFields.size() > 0;
                        PropertyRestriction restriction = filter.getPropertyRestriction(QueryConstants.OAK_SCORE_EXPLANATION);
                        boolean addExplain = restriction != null && restriction.isNotNullRestriction();
                        Analyzer analyzer = indexNode.getDefinition().getAnalyzer();
                        FieldInfos mergedFieldInfos = null;
                        if (addExcerpt) {
                            // setup highlighter
                            QueryScorer scorer = new QueryScorer(query);
                            scorer.setExpandMultiTermQuery(true);
                            highlighter.setFragmentScorer(scorer);
                            mergedFieldInfos = MultiFields.getMergedFieldInfos(searcher.getIndexReader());
                        }
                        for (ScoreDoc doc : docs.scoreDocs) {
                            Map<String, String> excerpts = null;
                            if (addExcerpt) {
                                excerpts = getExcerpt(query, excerptFields, analyzer, searcher, doc, mergedFieldInfos);
                            }
                            String explanation = null;
                            if (addExplain) {
                                explanation = searcher.explain(query, doc.doc).toString();
                            }
                            LuceneResultRow row = convertToRow(doc, searcher, excerpts, facets, explanation);
                            if (row != null) {
                                queue.add(row);
                            }
                            lastDocToRecord = doc;
                        }
                        if (queue.isEmpty() && docs.scoreDocs.length > 0) {
                            // queue is still empty but more results can be fetched
                            // from Lucene so still continue
                            lastDoc = lastDocToRecord;
                        } else {
                            break;
                        }
                    }
                } else if (luceneRequestFacade.getLuceneRequest() instanceof SpellcheckHelper.SpellcheckQuery) {
                    String aclCheckField = indexNode.getDefinition().isFullTextEnabled() ? FieldNames.FULLTEXT : FieldNames.SPELLCHECK;
                    noDocs = true;
                    SpellcheckHelper.SpellcheckQuery spellcheckQuery = (SpellcheckHelper.SpellcheckQuery) luceneRequestFacade.getLuceneRequest();
                    SuggestWord[] suggestWords = SpellcheckHelper.getSpellcheck(spellcheckQuery);
                    // ACL filter spellchecks
                    QueryParser qp = new QueryParser(Version.LUCENE_47, aclCheckField, indexNode.getDefinition().getAnalyzer());
                    for (SuggestWord suggestion : suggestWords) {
                        Query query = qp.createPhraseQuery(aclCheckField, QueryParserBase.escape(suggestion.string));
                        query = addDescendantClauseIfRequired(query, plan);
                        TopDocs topDocs = searcher.search(query, 100);
                        if (topDocs.totalHits > 0) {
                            for (ScoreDoc doc : topDocs.scoreDocs) {
                                Document retrievedDoc = searcher.doc(doc.doc);
                                String prefix = filter.getPath();
                                if (prefix.length() == 1) {
                                    prefix = "";
                                }
                                if (filter.isAccessible(prefix + retrievedDoc.get(FieldNames.PATH))) {
                                    queue.add(new LuceneResultRow(suggestion.string));
                                    break;
                                }
                            }
                        }
                    }
                } else if (luceneRequestFacade.getLuceneRequest() instanceof SuggestHelper.SuggestQuery) {
                    SuggestHelper.SuggestQuery suggestQuery = (SuggestHelper.SuggestQuery) luceneRequestFacade.getLuceneRequest();
                    noDocs = true;
                    List<Lookup.LookupResult> lookupResults = SuggestHelper.getSuggestions(indexNode.getLookup(), suggestQuery);
                    QueryParser qp = new QueryParser(Version.LUCENE_47, FieldNames.SUGGEST, indexNode.getDefinition().isSuggestAnalyzed() ? indexNode.getDefinition().getAnalyzer() : SuggestHelper.getAnalyzer());
                    // ACL filter suggestions
                    for (Lookup.LookupResult suggestion : lookupResults) {
                        Query query = qp.parse("\"" + QueryParserBase.escape(suggestion.key.toString()) + "\"");
                        query = addDescendantClauseIfRequired(query, plan);
                        TopDocs topDocs = searcher.search(query, 100);
                        if (topDocs.totalHits > 0) {
                            for (ScoreDoc doc : topDocs.scoreDocs) {
                                Document retrievedDoc = searcher.doc(doc.doc);
                                String prefix = filter.getPath();
                                if (prefix.length() == 1) {
                                    prefix = "";
                                }
                                if (filter.isAccessible(prefix + retrievedDoc.get(FieldNames.PATH))) {
                                    queue.add(new LuceneResultRow(suggestion.key.toString(), suggestion.value));
                                    break;
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                LOG.warn("query via {} failed.", LucenePropertyIndex.this, e);
            } finally {
                indexNode.release();
            }
            if (lastDocToRecord != null) {
                this.lastDoc = lastDocToRecord;
            }
            return !queue.isEmpty();
        }

        private IndexSearcher getCurrentSearcher(IndexNode indexNode) {
            // the searcher would be refreshed as done earlier
            if (indexNodeId != indexNode.getIndexNodeId()) {
                // if already initialized then log about change
                if (indexNodeId > 0) {
                    LOG.debug("Change in index version detected. Query would be performed without offset");
                }
                indexSearcher = indexNode.getSearcher();
                indexNodeId = indexNode.getIndexNodeId();
                lastDoc = null;
            }
            return indexSearcher;
        }

        private void releaseSearcher() {
            // For now nullifying it.
            indexSearcher = null;
        }
    };
    SizeEstimator sizeEstimator = new SizeEstimator() {

        @Override
        public long getSize() {
            IndexNode indexNode = acquireIndexNode(plan);
            checkState(indexNode != null);
            try {
                IndexSearcher searcher = indexNode.getSearcher();
                LuceneRequestFacade luceneRequestFacade = getLuceneRequest(plan, augmentorFactory, searcher.getIndexReader());
                if (luceneRequestFacade.getLuceneRequest() instanceof Query) {
                    Query query = (Query) luceneRequestFacade.getLuceneRequest();
                    TotalHitCountCollector collector = new TotalHitCountCollector();
                    searcher.search(query, collector);
                    int totalHits = collector.getTotalHits();
                    LOG.debug("Estimated size for query {} is {}", query, totalHits);
                    return totalHits;
                }
                LOG.debug("estimate size: not a Query: {}", luceneRequestFacade.getLuceneRequest());
            } catch (IOException e) {
                LOG.warn("query via {} failed.", LucenePropertyIndex.this, e);
            } finally {
                indexNode.release();
            }
            return -1;
        }
    };
    if (pr.hasPropertyIndexResult() || pr.evaluateSyncNodeTypeRestriction()) {
        itr = mergePropertyIndexResult(plan, rootState, itr);
    }
    return new LucenePathCursor(itr, plan, settings, sizeEstimator);
}
Also used : IndexSearcher(org.apache.lucene.search.IndexSearcher) PlanResult(org.apache.jackrabbit.oak.plugins.index.lucene.IndexPlanner.PlanResult) Set(java.util.Set) Facets(org.apache.lucene.facet.Facets) 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) Analyzer(org.apache.lucene.analysis.Analyzer) Document(org.apache.lucene.document.Document) ScoreDoc(org.apache.lucene.search.ScoreDoc) QueryLimits(org.apache.jackrabbit.oak.spi.query.QueryLimits) TopDocs(org.apache.lucene.search.TopDocs) PathStoredFieldVisitor(org.apache.jackrabbit.oak.plugins.index.lucene.util.PathStoredFieldVisitor) CustomScoreQuery(org.apache.lucene.queries.CustomScoreQuery) Sort(org.apache.lucene.search.Sort) Lookup(org.apache.lucene.search.suggest.Lookup) HybridPropertyIndexLookup(org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexLookup) TotalHitCountCollector(org.apache.lucene.search.TotalHitCountCollector) AbstractIterator(com.google.common.collect.AbstractIterator) PropertyRestriction(org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction) QueryScorer(org.apache.lucene.search.highlight.QueryScorer) SuggestHelper(org.apache.jackrabbit.oak.plugins.index.lucene.util.SuggestHelper) IOException(java.io.IOException) Deque(java.util.Deque) QueryNodeException(org.apache.lucene.queryparser.flexible.core.QueryNodeException) ParseException(org.apache.lucene.queryparser.classic.ParseException) IOException(java.io.IOException) InvalidTokenOffsetsException(org.apache.lucene.search.highlight.InvalidTokenOffsetsException) FieldInfos(org.apache.lucene.index.FieldInfos) StandardQueryParser(org.apache.lucene.queryparser.flexible.standard.StandardQueryParser) QueryParser(org.apache.lucene.queryparser.classic.QueryParser) Filter(org.apache.jackrabbit.oak.spi.query.Filter) IndexReader(org.apache.lucene.index.IndexReader) SuggestWord(org.apache.lucene.search.spell.SuggestWord) SpellcheckHelper(org.apache.jackrabbit.oak.plugins.index.lucene.util.SpellcheckHelper) Map(java.util.Map)

Example 14 with PropertyRestriction

use of org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction in project jackrabbit-oak by apache.

the class LucenePropertyIndex method addNonFullTextConstraints.

private static void addNonFullTextConstraints(List<Query> qs, IndexPlan plan, IndexReader reader) {
    Filter filter = plan.getFilter();
    PlanResult planResult = getPlanResult(plan);
    IndexDefinition defn = planResult.indexDefinition;
    if (!filter.matchesAllTypes()) {
        addNodeTypeConstraints(planResult.indexingRule, qs, filter);
    }
    String path = getPathRestriction(plan);
    switch(filter.getPathRestriction()) {
        case ALL_CHILDREN:
            if (defn.evaluatePathRestrictions()) {
                if ("/".equals(path)) {
                    break;
                }
                qs.add(new TermQuery(newAncestorTerm(path)));
            }
            break;
        case DIRECT_CHILDREN:
            if (defn.evaluatePathRestrictions()) {
                BooleanQuery bq = new BooleanQuery();
                bq.add(new BooleanClause(new TermQuery(newAncestorTerm(path)), BooleanClause.Occur.MUST));
                bq.add(new BooleanClause(newDepthQuery(path), BooleanClause.Occur.MUST));
                qs.add(bq);
            }
            break;
        case EXACT:
            qs.add(new TermQuery(newPathTerm(path)));
            break;
        case PARENT:
            if (denotesRoot(path)) {
                // there's no parent of the root node
                // we add a path that can not possibly occur because there
                // is no way to say "match no documents" in Lucene
                qs.add(new TermQuery(new Term(FieldNames.PATH, "///")));
            } else {
                qs.add(new TermQuery(newPathTerm(getParentPath(path))));
            }
            break;
        case NO_RESTRICTION:
            break;
    }
    for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
        String name = pr.propertyName;
        if (QueryConstants.REP_EXCERPT.equals(name) || QueryConstants.OAK_SCORE_EXPLANATION.equals(name) || QueryConstants.REP_FACET.equals(name)) {
            continue;
        }
        if (QueryConstants.RESTRICTION_LOCAL_NAME.equals(name)) {
            if (planResult.evaluateNodeNameRestriction()) {
                Query q = createNodeNameQuery(pr);
                if (q != null) {
                    qs.add(q);
                }
            }
            continue;
        }
        if (pr.first != null && pr.first.equals(pr.last) && pr.firstIncluding && pr.lastIncluding) {
            String first = pr.first.getValue(STRING);
            first = first.replace("\\", "");
            if (JCR_PATH.equals(name)) {
                qs.add(new TermQuery(newPathTerm(first)));
                continue;
            } else if ("*".equals(name)) {
                // TODO Revisit reference constraint. For performant impl
                // references need to be indexed in a different manner
                addReferenceConstraint(first, qs, reader);
                continue;
            }
        }
        PropertyDefinition pd = planResult.getPropDefn(pr);
        if (pd == null) {
            continue;
        }
        Query q = createQuery(planResult.getPropertyName(pr), pr, pd);
        if (q != null) {
            qs.add(q);
        }
    }
}
Also used : BooleanClause(org.apache.lucene.search.BooleanClause) TermQuery(org.apache.lucene.search.TermQuery) BooleanQuery(org.apache.lucene.search.BooleanQuery) 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) Filter(org.apache.jackrabbit.oak.spi.query.Filter) Term(org.apache.lucene.index.Term) TermFactory.newAncestorTerm(org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newAncestorTerm) FullTextTerm(org.apache.jackrabbit.oak.spi.query.fulltext.FullTextTerm) TermFactory.newPathTerm(org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newPathTerm)

Example 15 with PropertyRestriction

use of org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction in project jackrabbit-oak by apache.

the class IndexPlanner method wrongIndex.

private boolean wrongIndex() {
    // REMARK: similar code is used in oak-core, PropertyIndex
    // skip index if "option(index ...)" doesn't match
    PropertyRestriction indexName = filter.getPropertyRestriction(IndexConstants.INDEX_NAME_OPTION);
    boolean wrong = false;
    if (indexName != null && indexName.first != null) {
        String name = indexName.first.getValue(Type.STRING);
        String thisName = definition.getIndexName();
        if (thisName != null) {
            thisName = PathUtils.getName(thisName);
            if (thisName.equals(name)) {
                // index name specified, and matches
                return false;
            }
        }
        wrong = true;
    }
    PropertyRestriction indexTag = filter.getPropertyRestriction(IndexConstants.INDEX_TAG_OPTION);
    if (indexTag != null && indexTag.first != null) {
        // index tag specified
        String[] tags = definition.getIndexTags();
        if (tags == null) {
            // no tag
            return true;
        }
        String tag = indexTag.first.getValue(Type.STRING);
        for (String t : tags) {
            if (t.equals(tag)) {
                // tag matches
                return false;
            }
        }
        // no tag matches
        return true;
    }
    // no tag specified
    return wrong;
}
Also used : PropertyRestriction(org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction)

Aggregations

PropertyRestriction (org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction)15 PrefixQuery (org.apache.lucene.search.PrefixQuery)6 TermQuery (org.apache.lucene.search.TermQuery)6 WildcardQuery (org.apache.lucene.search.WildcardQuery)6 BooleanQuery (org.apache.lucene.search.BooleanQuery)5 MatchAllDocsQuery (org.apache.lucene.search.MatchAllDocsQuery)5 Query (org.apache.lucene.search.Query)5 TermRangeQuery (org.apache.lucene.search.TermRangeQuery)5 ArrayList (java.util.ArrayList)4 Filter (org.apache.jackrabbit.oak.spi.query.Filter)4 FullTextExpression (org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression)4 Analyzer (org.apache.lucene.analysis.Analyzer)4 QueryParser (org.apache.lucene.queryparser.classic.QueryParser)4 PlanResult (org.apache.jackrabbit.oak.plugins.index.lucene.IndexPlanner.PlanResult)3 SpellcheckHelper (org.apache.jackrabbit.oak.plugins.index.lucene.util.SpellcheckHelper)3 SuggestHelper (org.apache.jackrabbit.oak.plugins.index.lucene.util.SuggestHelper)3 CustomScoreQuery (org.apache.lucene.queries.CustomScoreQuery)3 ParseException (org.apache.lucene.queryparser.classic.ParseException)3 NumericRangeQuery (org.apache.lucene.search.NumericRangeQuery)3 AbstractIterator (com.google.common.collect.AbstractIterator)2