Search in sources :

Example 6 with FullTextTerm

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

the class IndexPlanner method canEvalAllFullText.

private boolean canEvalAllFullText(final IndexingRule indexingRule, FullTextExpression ft) {
    if (ft == null) {
        return false;
    }
    final HashSet<String> relPaths = new HashSet<String>();
    final HashSet<String> nonIndexedPaths = new HashSet<String>();
    final AtomicBoolean relativeParentsFound = new AtomicBoolean();
    final AtomicBoolean nodeScopedCondition = new AtomicBoolean();
    ft.accept(new FullTextVisitor.FullTextVisitorBase() {

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

        @Override
        public boolean visit(FullTextTerm term) {
            visitTerm(term.getPropertyName());
            return true;
        }

        private void visitTerm(String propertyName) {
            String p = propertyName;
            String propertyPath = null;
            String nodePath = null;
            if (p == null) {
                relPaths.add("");
            } else if (p.startsWith("../") || p.startsWith("./")) {
                relPaths.add(p);
                relativeParentsFound.set(true);
            } else if (getDepth(p) > 1) {
                String parent = getParentPath(p);
                if (LucenePropertyIndex.isNodePath(p)) {
                    nodePath = parent;
                } else {
                    propertyPath = p;
                }
                relPaths.add(parent);
            } else {
                propertyPath = p;
                relPaths.add("");
            }
            if (nodePath != null && !indexingRule.isAggregated(nodePath)) {
                nonIndexedPaths.add(p);
            } else if (propertyPath != null) {
                PropertyDefinition pd = indexingRule.getConfig(propertyPath);
                //not indexed
                if (pd == null) {
                    nonIndexedPaths.add(p);
                } else if (!pd.analyzed) {
                    nonIndexedPaths.add(p);
                }
            }
            if (nodeScopedTerm(propertyName)) {
                nodeScopedCondition.set(true);
            }
        }
    });
    if (nodeScopedCondition.get() && !indexingRule.isNodeFullTextIndexed()) {
        return false;
    }
    if (relativeParentsFound.get()) {
        log.debug("Relative parents found {} which are not supported", relPaths);
        return false;
    }
    //have jcr:content as parent. So ensure that relPaths size is 1 or 0
    if (!nonIndexedPaths.isEmpty()) {
        if (relPaths.size() > 1) {
            log.debug("Following relative  property paths are not index", relPaths);
            return false;
        }
        result.setParentPath(Iterables.getOnlyElement(relPaths, ""));
        //Such non indexed path can possibly be evaluated via any rule on nt:base
        //which can possibly index everything
        IndexingRule rule = definition.getApplicableIndexingRule(NT_BASE);
        if (rule == null) {
            return false;
        }
        for (String p : nonIndexedPaths) {
            //if it indexes node scope indexing is enabled
            if (LucenePropertyIndex.isNodePath(p)) {
                if (!rule.isNodeFullTextIndexed()) {
                    return false;
                }
            } else {
                //Index can only evaluate a property like jcr:content/type
                //if it indexes 'type' and that too analyzed
                String propertyName = PathUtils.getName(p);
                PropertyDefinition pd = rule.getConfig(propertyName);
                if (pd == null) {
                    return false;
                }
                if (!pd.analyzed) {
                    return false;
                }
            }
        }
    } else {
        result.setParentPath("");
    }
    return true;
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) FullTextVisitor(org.apache.jackrabbit.oak.query.fulltext.FullTextVisitor) FullTextTerm(org.apache.jackrabbit.oak.query.fulltext.FullTextTerm) IndexingRule(org.apache.jackrabbit.oak.plugins.index.lucene.IndexDefinition.IndexingRule) FullTextContains(org.apache.jackrabbit.oak.query.fulltext.FullTextContains) HashSet(java.util.HashSet)

Example 7 with FullTextTerm

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

the class LuceneIndex method getFullTextQuery.

static Query getFullTextQuery(FullTextExpression ft, final Analyzer analyzer, final IndexReader reader) {
    // 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) {
            return contains.getBase().accept(this);
        }

        @Override
        public boolean visit(FullTextOr or) {
            BooleanQuery q = new BooleanQuery();
            for (FullTextExpression e : or.list) {
                Query x = getFullTextQuery(e, analyzer, reader);
                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(e, analyzer, reader);
                /* 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 = propertyName;
            if (p != null && p.indexOf('/') >= 0) {
                p = getName(p);
            }
            Query q = tokenToQuery(text, p, analyzer, reader);
            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) 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) FullTextOr(org.apache.jackrabbit.oak.query.fulltext.FullTextOr) FullTextContains(org.apache.jackrabbit.oak.query.fulltext.FullTextContains) AtomicReference(java.util.concurrent.atomic.AtomicReference) FullTextVisitor(org.apache.jackrabbit.oak.query.fulltext.FullTextVisitor) FullTextTerm(org.apache.jackrabbit.oak.query.fulltext.FullTextTerm) FullTextAnd(org.apache.jackrabbit.oak.query.fulltext.FullTextAnd) FullTextExpression(org.apache.jackrabbit.oak.query.fulltext.FullTextExpression)

Example 8 with FullTextTerm

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

the class LuceneIndexTest method customScoreQuery.

@Test
public void customScoreQuery() throws Exception {
    NodeBuilder nb = newLuceneIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "lucene", of(TYPENAME_STRING));
    TestUtil.useV2(nb);
    nb.setProperty(LuceneIndexConstants.PROP_SCORER_PROVIDER, "testScorer");
    NodeState before = builder.getNodeState();
    builder.child("a").setProperty("jcr:createdBy", "bar bar");
    builder.child("b").setProperty("jcr:createdBy", "foo bar");
    NodeState after = builder.getNodeState();
    NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
    tracker = new IndexTracker();
    tracker.update(indexed);
    SimpleScorerFactory factory = new SimpleScorerFactory();
    ScorerProvider provider = new ScorerProvider() {

        String scorerName = "testScorer";

        @Override
        public String getName() {
            return scorerName;
        }

        @Override
        public CustomScoreQuery createCustomScoreQuery(Query query) {
            return new ModifiedCustomScoreQuery(query);
        }

        class ModifiedCustomScoreQuery extends CustomScoreQuery {

            private Query query;

            public ModifiedCustomScoreQuery(Query query) {
                super(query);
                this.query = query;
            }

            @Override
            public CustomScoreProvider getCustomScoreProvider(AtomicReaderContext context) {
                return new CustomScoreProvider(context) {

                    public float customScore(int doc, float subQueryScore, float valSrcScore) {
                        AtomicReader atomicReader = context.reader();
                        try {
                            Document document = atomicReader.document(doc);
                            // boosting docs created by foo
                            String fieldValue = document.get("full:jcr:createdBy");
                            if (fieldValue != null && fieldValue.contains("foo")) {
                                valSrcScore *= 2.0;
                            }
                        } catch (IOException e) {
                            return subQueryScore * valSrcScore;
                        }
                        return subQueryScore * valSrcScore;
                    }
                };
            }
        }
    };
    factory.providers.put(provider.getName(), provider);
    AdvancedQueryIndex queryIndex = new LucenePropertyIndex(tracker, factory);
    FilterImpl filter = createFilter(NT_BASE);
    filter.setFullTextConstraint(new FullTextTerm(null, "bar", false, false, null));
    assertFilter(filter, queryIndex, indexed, asList("/b", "/a"), true);
}
Also used : NodeState(org.apache.jackrabbit.oak.spi.state.NodeState) FilterImpl(org.apache.jackrabbit.oak.query.index.FilterImpl) Query(org.apache.lucene.search.Query) CustomScoreQuery(org.apache.lucene.queries.CustomScoreQuery) AtomicReader(org.apache.lucene.index.AtomicReader) IOException(java.io.IOException) NodeBuilder(org.apache.jackrabbit.oak.spi.state.NodeBuilder) Document(org.apache.lucene.document.Document) AdvancedQueryIndex(org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex) ScorerProvider(org.apache.jackrabbit.oak.plugins.index.lucene.score.ScorerProvider) FullTextTerm(org.apache.jackrabbit.oak.query.fulltext.FullTextTerm) CustomScoreProvider(org.apache.lucene.queries.CustomScoreProvider) AtomicReaderContext(org.apache.lucene.index.AtomicReaderContext) Test(org.junit.Test)

Example 9 with FullTextTerm

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

the class FilterQueryParser method parseFullTextExpression.

private static String parseFullTextExpression(FullTextExpression ft, final OakSolrConfiguration configuration) {
    final StringBuilder fullTextString = new StringBuilder();
    ft.accept(new FullTextVisitor() {

        @Override
        public boolean visit(FullTextOr or) {
            fullTextString.append('(');
            for (int i = 0; i < or.list.size(); i++) {
                if (i > 0 && i < or.list.size()) {
                    fullTextString.append(" OR ");
                }
                FullTextExpression e = or.list.get(i);
                String orTerm = parseFullTextExpression(e, configuration);
                fullTextString.append(orTerm);
            }
            fullTextString.append(')');
            fullTextString.append(' ');
            return true;
        }

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

        @Override
        public boolean visit(FullTextAnd and) {
            fullTextString.append('(');
            for (int i = 0; i < and.list.size(); i++) {
                if (i > 0 && i < and.list.size()) {
                    fullTextString.append(" AND ");
                }
                FullTextExpression e = and.list.get(i);
                String andTerm = parseFullTextExpression(e, configuration);
                fullTextString.append(andTerm);
            }
            fullTextString.append(')');
            fullTextString.append(' ');
            return true;
        }

        @Override
        public boolean visit(FullTextTerm term) {
            if (term.isNot()) {
                fullTextString.append('-');
            }
            String p = term.getPropertyName();
            if (p != null && p.indexOf('/') >= 0) {
                p = getName(p);
            }
            if (p == null || "*".equals(p)) {
                p = configuration.getCatchAllField();
            }
            fullTextString.append(partialEscape(p));
            fullTextString.append(':');
            String termText = term.getText();
            if (termText.indexOf(' ') > 0) {
                fullTextString.append('"');
            }
            fullTextString.append(termText.replace("/", "\\/").replace(":", "\\:"));
            if (termText.indexOf(' ') > 0) {
                fullTextString.append('"');
            }
            String boost = term.getBoost();
            if (boost != null) {
                fullTextString.append('^');
                fullTextString.append(boost);
            }
            fullTextString.append(' ');
            return true;
        }
    });
    return fullTextString.toString();
}
Also used : FullTextVisitor(org.apache.jackrabbit.oak.query.fulltext.FullTextVisitor) FullTextTerm(org.apache.jackrabbit.oak.query.fulltext.FullTextTerm) FullTextOr(org.apache.jackrabbit.oak.query.fulltext.FullTextOr) FullTextContains(org.apache.jackrabbit.oak.query.fulltext.FullTextContains) FullTextAnd(org.apache.jackrabbit.oak.query.fulltext.FullTextAnd) FullTextExpression(org.apache.jackrabbit.oak.query.fulltext.FullTextExpression)

Aggregations

FullTextTerm (org.apache.jackrabbit.oak.query.fulltext.FullTextTerm)9 FullTextContains (org.apache.jackrabbit.oak.query.fulltext.FullTextContains)6 FullTextVisitor (org.apache.jackrabbit.oak.query.fulltext.FullTextVisitor)6 FullTextAnd (org.apache.jackrabbit.oak.query.fulltext.FullTextAnd)5 FullTextExpression (org.apache.jackrabbit.oak.query.fulltext.FullTextExpression)5 FullTextOr (org.apache.jackrabbit.oak.query.fulltext.FullTextOr)5 AtomicReference (java.util.concurrent.atomic.AtomicReference)4 Query (org.apache.lucene.search.Query)3 Test (org.junit.Test)3 FilterImpl (org.apache.jackrabbit.oak.query.index.FilterImpl)2 AdvancedQueryIndex (org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex)2 NodeBuilder (org.apache.jackrabbit.oak.spi.state.NodeBuilder)2 NodeState (org.apache.jackrabbit.oak.spi.state.NodeState)2 CustomScoreQuery (org.apache.lucene.queries.CustomScoreQuery)2 BooleanQuery (org.apache.lucene.search.BooleanQuery)2 MatchAllDocsQuery (org.apache.lucene.search.MatchAllDocsQuery)2 PrefixQuery (org.apache.lucene.search.PrefixQuery)2 TermQuery (org.apache.lucene.search.TermQuery)2 TermRangeQuery (org.apache.lucene.search.TermRangeQuery)2 WildcardQuery (org.apache.lucene.search.WildcardQuery)2