You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ch...@apache.org on 2016/08/17 09:44:57 UTC

svn commit: r1756603 - in /jackrabbit/oak/branches/1.4: ./ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/ oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/

Author: chetanm
Date: Wed Aug 17 09:44:57 2016
New Revision: 1756603

URL: http://svn.apache.org/viewvc?rev=1756603&view=rev
Log:
OAK-4676 -  Index definition on nt:base with analyzed property incorrectly matches query with different property

Merging 1756520,1756580

Modified:
    jackrabbit/oak/branches/1.4/   (props changed)
    jackrabbit/oak/branches/1.4/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
    jackrabbit/oak/branches/1.4/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
    jackrabbit/oak/branches/1.4/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
    jackrabbit/oak/branches/1.4/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java

Propchange: jackrabbit/oak/branches/1.4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Aug 17 09:44:57 2016
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1733615,1733875,1733913,1733929,1734230,1734254,1734279,1734941,1735052,1735267,1735405,1735484,1735549,1735564,1735588,1735622,1735638,1735919,1735983,1736176,1737309-1737310,1737334,1737349,1737998,1738004,1738775,1738795,1738833,1738950,1738957,1738963,1739894,1740116,1740625-1740626,1740971,1741032,1741339,1741343,1742520,1742888,1742916,1743097,1743172,1743343,1744265,1744959,1745038,1745197,1745368,1746086,1746117,1746342,1746345,1746696,1746981,1747341-1747342,1747492,1747512,1748505,1748553,1748722,1748870,1749275,1749350,1749464,1749475,1749645,1749662,1749815,1749872,1749875,1749899,1750052,1750076-1750077,1750287,1750457,1750462,1750465,1750495,1750626,1750809,1750886,1751410,1751445-1751446,1751478,1751755,1751871,1752198,1752202,1752273-1752274,1752438,1752447,1752508,1752616,1752659,1752672,1753262,1753331-1753332,1753355,1753444,1754117,1754239,1755157
+/jackrabbit/oak/trunk:1733615,1733875,1733913,1733929,1734230,1734254,1734279,1734941,1735052,1735267,1735405,1735484,1735549,1735564,1735588,1735622,1735638,1735919,1735983,1736176,1737309-1737310,1737334,1737349,1737998,1738004,1738775,1738795,1738833,1738950,1738957,1738963,1739894,1740116,1740625-1740626,1740971,1741032,1741339,1741343,1742520,1742888,1742916,1743097,1743172,1743343,1744265,1744959,1745038,1745197,1745368,1746086,1746117,1746342,1746345,1746696,1746981,1747341-1747342,1747492,1747512,1748505,1748553,1748722,1748870,1749275,1749350,1749464,1749475,1749645,1749662,1749815,1749872,1749875,1749899,1750052,1750076-1750077,1750287,1750457,1750462,1750465,1750495,1750626,1750809,1750886,1751410,1751445-1751446,1751478,1751755,1751871,1752198,1752202,1752273-1752274,1752438,1752447,1752508,1752616,1752659,1752672,1753262,1753331-1753332,1753355,1753444,1754117,1754239,1755157,1756520,1756580
 /jackrabbit/trunk:1345480

Modified: jackrabbit/oak/branches/1.4/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java?rev=1756603&r1=1756602&r2=1756603&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java (original)
+++ jackrabbit/oak/branches/1.4/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java Wed Aug 17 09:44:57 2016
@@ -374,10 +374,6 @@ class IndexDefinition implements Aggrega
         return evaluatePathRestrictions;
     }
 
-    public boolean indexesAllTypes() {
-        return indexesAllTypes;
-    }
-
     public Analyzer getAnalyzer(){
         return analyzer;
     }

Modified: jackrabbit/oak/branches/1.4/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java?rev=1756603&r1=1756602&r2=1756603&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java (original)
+++ jackrabbit/oak/branches/1.4/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java Wed Aug 17 09:44:57 2016
@@ -50,6 +50,7 @@ import static com.google.common.collect.
 import static com.google.common.collect.Lists.newArrayListWithCapacity;
 import static com.google.common.collect.Maps.newHashMap;
 import static org.apache.jackrabbit.JcrConstants.JCR_SCORE;
+import static org.apache.jackrabbit.JcrConstants.NT_BASE;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getAncestorPath;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getDepth;
 import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
@@ -348,9 +349,15 @@ class IndexPlanner {
                 if (nodePath != null
                         && !indexingRule.isAggregated(nodePath)){
                     nonIndexedPaths.add(p);
-                } else if (propertyPath != null
-                        && !indexingRule.isIndexed(propertyPath)){
-                    nonIndexedPaths.add(p);
+                } else if (propertyPath != null) {
+                    PropertyDefinition pd = indexingRule.getConfig(propertyPath);
+                    //If given prop is not analyzed then its
+                    //not indexed
+                    if (pd == null){
+                        nonIndexedPaths.add(p);
+                    } else if (!pd.analyzed){
+                        nonIndexedPaths.add(p);
+                    }
                 }
 
                 if (nodeScopedTerm(propertyName)){
@@ -368,15 +375,44 @@ class IndexPlanner {
             return false;
         }
 
+        //where contains('jcr:content/bar', 'mountain OR valley') and contains('jcr:content/foo', 'mountain OR valley')
+        //above query can be evaluated by index which indexes foo and bar with restriction that both belong to same node
+        //by displacing the query path to evaluate on contains('bar', ...) and filter out those parents which do not
+        //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 path translation would only work if index contains
-            //all the nodes
-            return definition.indexesAllTypes();
+
+            //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){
+                //Index can only evaluate a node search jcr:content/*
+                //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("");
         }

Modified: jackrabbit/oak/branches/1.4/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java?rev=1756603&r1=1756602&r2=1756603&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java Wed Aug 17 09:44:57 2016
@@ -20,6 +20,7 @@
 package org.apache.jackrabbit.oak.plugins.index.lucene;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collections;
 
 import javax.annotation.Nonnull;
@@ -31,6 +32,9 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.query.QueryEngineSettings;
 import org.apache.jackrabbit.oak.query.ast.Operator;
 import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
+import org.apache.jackrabbit.oak.query.fulltext.FullTextAnd;
+import org.apache.jackrabbit.oak.query.fulltext.FullTextContains;
+import org.apache.jackrabbit.oak.query.fulltext.FullTextExpression;
 import org.apache.jackrabbit.oak.query.fulltext.FullTextParser;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -555,6 +559,178 @@ public class IndexPlannerTest {
         assertNull(plan);
     }
 
+    @Test
+    public void fullTextQuery_RelativePath1() throws Exception{
+        NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("foo"), "async");
+
+        defn = IndexDefinition.updateDefinition(defn.getNodeState().builder());
+        NodeBuilder foob = getNode(defn, "indexRules/nt:base/properties/foo");
+        foob.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+
+        IndexPlanner planner = createPlannerForFulltext(defn.getNodeState(), FullTextParser.parse("bar", "mountain"));
+
+        //No plan for unindex property
+        assertNull(planner.getPlan());
+    }
+
+    @Test
+    public void fullTextQuery_IndexAllProps() throws Exception{
+        NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("allProps"), "async");
+
+        //Index all props and then perform fulltext
+        defn = IndexDefinition.updateDefinition(defn.getNodeState().builder());
+        NodeBuilder foob = getNode(defn, "indexRules/nt:base/properties/allProps");
+        foob.setProperty(LuceneIndexConstants.PROP_NAME, LuceneIndexConstants.REGEX_ALL_PROPS);
+        foob.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+        foob.setProperty(LuceneIndexConstants.PROP_IS_REGEX, true);
+
+        FullTextExpression exp = FullTextParser.parse("bar", "mountain OR valley");
+        exp = new FullTextContains("bar", "mountain OR valley", exp);
+        IndexPlanner planner = createPlannerForFulltext(defn.getNodeState(), exp);
+
+        //No plan for unindex property
+        assertNotNull(planner.getPlan());
+    }
+
+    @Test
+    public void fullTextQuery_IndexAllProps_NodePathQuery() throws Exception{
+        NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("allProps"), "async");
+
+        //Index all props and then perform fulltext
+        defn = IndexDefinition.updateDefinition(defn.getNodeState().builder());
+        NodeBuilder foob = getNode(defn, "indexRules/nt:base/properties/allProps");
+        foob.setProperty(LuceneIndexConstants.PROP_NAME, LuceneIndexConstants.REGEX_ALL_PROPS);
+        foob.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+        foob.setProperty(LuceneIndexConstants.PROP_NODE_SCOPE_INDEX, true);
+        foob.setProperty(LuceneIndexConstants.PROP_IS_REGEX, true);
+
+        //where contains('jcr:content/*', 'mountain OR valley') can be evaluated by index
+        //on nt:base by evaluating on '.' and then checking if node name is 'jcr:content'
+        IndexPlanner planner = createPlannerForFulltext(defn.getNodeState(),
+                FullTextParser.parse("jcr:content/*", "mountain OR valley"));
+
+        //No plan for unindex property
+        assertNotNull(planner.getPlan());
+    }
+
+    @Test
+    public void fullTextQuery_IndexAllProps_AggregatedNodePathQuery() throws Exception{
+        NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("allProps"), "async");
+
+        //Index all props and then perform fulltext
+        defn = IndexDefinition.updateDefinition(defn.getNodeState().builder());
+        NodeBuilder agg = defn.child(LuceneIndexConstants.AGGREGATES).child("nt:base").child("include0");
+        agg.setProperty(LuceneIndexConstants.AGG_PATH, "jcr:content");
+        agg.setProperty(LuceneIndexConstants.AGG_RELATIVE_NODE, true);
+
+        //where contains('jcr:content/*', 'mountain OR valley') can be evaluated by index
+        //on nt:base by evaluating on '.' and then checking if node name is 'jcr:content'
+        IndexPlanner planner = createPlannerForFulltext(defn.getNodeState(),
+                FullTextParser.parse("jcr:content/*", "mountain OR valley"));
+
+        //No plan for unindex property
+        assertNotNull(planner.getPlan());
+    }
+
+    @Test
+    public void fullTextQuery_IndexAllProps_NodePathQuery_NoPlan() throws Exception{
+        NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("foo"), "async");
+
+        //Index all props and then perform fulltext
+        defn = IndexDefinition.updateDefinition(defn.getNodeState().builder());
+        NodeBuilder foob = getNode(defn, "indexRules/nt:base/properties/foo");
+        foob.setProperty(LuceneIndexConstants.PROP_NAME, "foo");
+        foob.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+
+        //where contains('jcr:content/*', 'mountain OR valley') can be evaluated by index
+        //on nt:base by evaluating on '.' and then checking if node name is 'jcr:content'
+        IndexPlanner planner = createPlannerForFulltext(defn.getNodeState(),
+                FullTextParser.parse("jcr:content/*", "mountain OR valley"));
+
+        //No plan for unindex property
+        assertNull(planner.getPlan());
+    }
+
+    @Test
+    public void fullTextQuery_NonAnalyzedProp_NoPlan() throws Exception{
+        NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("foo", "bar"), "async");
+
+        //Index all props and then perform fulltext
+        defn = IndexDefinition.updateDefinition(defn.getNodeState().builder());
+        NodeBuilder foob = getNode(defn, "indexRules/nt:base/properties/foo");
+        foob.setProperty(LuceneIndexConstants.PROP_NAME, "foo");
+
+        NodeBuilder barb = getNode(defn, "indexRules/nt:base/properties/bar");
+        barb.setProperty(LuceneIndexConstants.PROP_NAME, "bar");
+        barb.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+
+        //where contains('jcr:content/*', 'mountain OR valley') can be evaluated by index
+        //on nt:base by evaluating on '.' and then checking if node name is 'jcr:content'
+        IndexPlanner planner = createPlannerForFulltext(defn.getNodeState(),
+                FullTextParser.parse("foo", "mountain OR valley"));
+
+        //No plan for unindex property
+        assertNull(planner.getPlan());
+    }
+
+    @Test
+    public void fullTextQuery_RelativePropertyPaths() throws Exception{
+        NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("foo", "bar"), "async");
+
+        //Index all props and then perform fulltext
+        defn = IndexDefinition.updateDefinition(defn.getNodeState().builder());
+        NodeBuilder foob = getNode(defn, "indexRules/nt:base/properties/foo");
+        foob.setProperty(LuceneIndexConstants.PROP_NAME, "foo");
+        foob.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+
+        NodeBuilder barb = getNode(defn, "indexRules/nt:base/properties/bar");
+        barb.setProperty(LuceneIndexConstants.PROP_NAME, "bar");
+        barb.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+
+
+        //where contains('jcr:content/bar', 'mountain OR valley') and contains('jcr:content/foo', 'mountain OR valley')
+        //above query can be evaluated by index which indexes foo and bar with restriction that both belong to same node
+        //by displacing the query path to evaluate on contains('bar', ...) and filter out those parents which do not
+        //have jcr:content as parent
+        FullTextExpression fooExp = FullTextParser.parse("jcr:content/bar", "mountain OR valley");
+        FullTextExpression barExp = FullTextParser.parse("jcr:content/foo", "mountain OR valley");
+        FullTextExpression exp = new FullTextAnd(Arrays.asList(fooExp, barExp));
+        IndexPlanner planner = createPlannerForFulltext(defn.getNodeState(),exp);
+
+        //No plan for unindex property
+        assertNotNull(planner.getPlan());
+    }
+
+    @Test
+    public void fullTextQuery_DisjointPropertyPaths() throws Exception{
+        NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("foo", "bar"), "async");
+
+        //Index all props and then perform fulltext
+        defn = IndexDefinition.updateDefinition(defn.getNodeState().builder());
+        NodeBuilder foob = getNode(defn, "indexRules/nt:base/properties/foo");
+        foob.setProperty(LuceneIndexConstants.PROP_NAME, "foo");
+        foob.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+
+        NodeBuilder barb = getNode(defn, "indexRules/nt:base/properties/bar");
+        barb.setProperty(LuceneIndexConstants.PROP_NAME, "bar");
+        barb.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+
+        FullTextExpression fooExp = FullTextParser.parse("metadata/bar", "mountain OR valley");
+        FullTextExpression barExp = FullTextParser.parse("jcr:content/foo", "mountain OR valley");
+        FullTextExpression exp = new FullTextAnd(Arrays.asList(fooExp, barExp));
+        IndexPlanner planner = createPlannerForFulltext(defn.getNodeState(),exp);
+
+        //No plan for unindex property
+        assertNull(planner.getPlan());
+    }
+
+    private IndexPlanner createPlannerForFulltext(NodeState defn, FullTextExpression exp) throws IOException {
+        IndexNode node = createIndexNode(new IndexDefinition(root, defn));
+        FilterImpl filter = createFilter("nt:base");
+        filter.setFullTextConstraint(exp);
+        return new IndexPlanner(node, "/foo", filter, Collections.<OrderEntry>emptyList());
+    }
+
     private IndexNode createSuggestionOrSpellcheckIndex(String nodeType,
                                                         boolean enableSuggestion,
                                                         boolean enableSpellcheck) throws Exception {

Modified: jackrabbit/oak/branches/1.4/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java?rev=1756603&r1=1756602&r2=1756603&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java Wed Aug 17 09:44:57 2016
@@ -98,6 +98,7 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INCLUDE_PROPERTY_NAMES;
 import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.ORDERED_PROP_NAMES;
 import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PROPDEF_PROP_NODE_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PROP_ANALYZED;
 import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PROP_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PROP_NODE;
 import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PROP_PROPERTY_INDEX;
@@ -1912,7 +1913,7 @@ public class LucenePropertyIndexTest ext
         Tree prop = props.addChild(TestUtil.unique("jcr:mimeType"));
         prop.setProperty(LuceneIndexConstants.PROP_NAME, "jcr:mimeType");
         prop.setProperty(LuceneIndexConstants.PROP_PROPERTY_INDEX, true);
-        prop.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+        prop.setProperty(PROP_ANALYZED, true);
         root.commit();
 
         Tree test = root.getTree("/").addChild("test");
@@ -1952,7 +1953,7 @@ public class LucenePropertyIndexTest ext
         Tree prop = props.addChild(TestUtil.unique("text"));
         prop.setProperty(LuceneIndexConstants.PROP_NAME, "text");
         prop.setProperty(LuceneIndexConstants.PROP_PROPERTY_INDEX, true);
-        prop.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+        prop.setProperty(PROP_ANALYZED, true);
         root.commit();
 
         Tree test = root.getTree("/").addChild("test");
@@ -2057,7 +2058,7 @@ public class LucenePropertyIndexTest ext
         Tree props = TestUtil.newRulePropTree(idx, "nt:base");
         Tree prop1 = props.addChild(TestUtil.unique("prop"));
         prop1.setProperty(LuceneIndexConstants.PROP_NAME, "tag");
-        prop1.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+        prop1.setProperty(PROP_ANALYZED, true);
         root.commit();
 
         Tree test = root.getTree("/").addChild("test");
@@ -2128,6 +2129,32 @@ public class LucenePropertyIndexTest ext
         assertPlanAndQuery(query, "lucene:test1(/oak:index/test1)", Collections.<String>emptyList());
     }
 
+    @Test
+    public void relativePropertyWithIndexOnNtBase() throws Exception {
+        Tree idx = createIndex("test1", of("propa"));
+        idx.setProperty(PROP_TYPE, "lucene");
+        useV2(idx);
+        //Do not provide type information
+        root.commit();
+
+        Tree propTree = root.getTree(idx.getPath() + "/indexRules/nt:base/properties/propa");
+        propTree.setProperty(PROP_ANALYZED, true);
+        root.commit();
+
+        Tree rootTree = root.getTree("/");
+        Tree node1Tree = rootTree.addChild("node1");
+        node1Tree.setProperty("propa", "abcdef");
+        node1Tree.setProperty("propb", "abcdef");
+        Tree node2Tree = rootTree.addChild("node2");
+        node2Tree.setProperty("propa", "abc_def");
+        node2Tree.setProperty("propb", "abc_def");
+        root.commit();
+
+        String query = "select [jcr:path] from [nt:base] where contains('propb', 'abc*')";
+        String explanation = explain(query);
+        assertThat(explanation, not(containsString("lucene:test1")));
+    }
+
     private void assertPlanAndQuery(String query, String planExpectation, List<String> paths){
         assertThat(explain(query), containsString(planExpectation));
         assertQuery(query, paths);
@@ -2163,7 +2190,7 @@ public class LucenePropertyIndexTest ext
         Tree prop = props.addChild(TestUtil.unique("prop"));
         prop.setProperty(LuceneIndexConstants.PROP_NAME, propName);
         prop.setProperty(LuceneIndexConstants.PROP_PROPERTY_INDEX, true);
-        prop.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+        prop.setProperty(PROP_ANALYZED, true);
         prop.setProperty(LuceneIndexConstants.PROP_NODE_SCOPE_INDEX, true);
         prop.setProperty(LuceneIndexConstants.FIELD_BOOST, boost);
         return prop;
@@ -2222,7 +2249,7 @@ public class LucenePropertyIndexTest ext
                 .addChild(LuceneIndexConstants.PROP_NODE)
                 .addChild("allProps");
 
-        props.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+        props.setProperty(PROP_ANALYZED, true);
         props.setProperty(LuceneIndexConstants.PROP_NODE_SCOPE_INDEX, true);
         props.setProperty(LuceneIndexConstants.PROP_USE_IN_EXCERPT, true);
         props.setProperty(LuceneIndexConstants.PROP_NAME, LuceneIndexConstants.REGEX_ALL_PROPS);