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 2014/11/26 09:06:53 UTC

svn commit: r1641771 [2/2] - in /jackrabbit/oak/trunk/oak-lucene/src: main/java/org/apache/jackrabbit/oak/plugins/index/lucene/ main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/ test/java/org/apache/jackrabbit/oak/plugins/index/lucene/

Added: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/AggregateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/AggregateTest.java?rev=1641771&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/AggregateTest.java (added)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/AggregateTest.java Wed Nov 26 08:06:52 2014
@@ -0,0 +1,416 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.plugins.index.lucene;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.index.lucene.Aggregate.NodeInclude;
+import org.apache.jackrabbit.oak.plugins.index.lucene.Aggregate.NodeIncludeResult;
+import org.apache.jackrabbit.oak.plugins.index.lucene.Aggregate.PropertyIncludeResult;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Test;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.ImmutableList.of;
+import static com.google.common.collect.Iterables.toArray;
+import static com.google.common.collect.Maps.newHashMap;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INDEX_RULES;
+import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
+import static org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.matchers.JUnitMatchers.hasItems;
+
+public class AggregateTest {
+
+    private final TestCollector col = new TestCollector();
+    private final SimpleMapper mapper = new SimpleMapper();
+    private final NodeState root = INITIAL_CONTENT;
+    private NodeBuilder builder = root.builder();
+
+    //~---------------------------------< Node Includes >
+
+    @Test
+    public void oneLevelAll() throws Exception{
+        Aggregate ag = new Aggregate("nt:base", of(ni("*")));
+        NodeBuilder nb = newNode("nt:base");
+        nb.child("a").child("c");
+        nb.child("b");
+
+        ag.collectAggregates(nb.getNodeState(), col);
+        assertEquals(2, col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems("a", "b"));
+    }
+
+    @Test
+    public void oneLevelNamed() throws Exception{
+        Aggregate ag = new Aggregate("nt:base", of(ni("a")));
+        NodeBuilder nb = newNode("nt:base");
+        nb.child("a");
+        nb.child("b");
+
+        ag.collectAggregates(nb.getNodeState(), col);
+        assertEquals(1, col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems("a"));
+    }
+
+    @Test
+    public void oneLevelTyped() throws Exception{
+        Aggregate ag = new Aggregate("nt:base", of(ni("nt:resource","*", false)));
+        NodeBuilder nb = newNode("nt:base");
+        nb.child("a").setProperty(JCR_PRIMARYTYPE,"nt:resource");
+        nb.child("b");
+
+        ag.collectAggregates(nb.getNodeState(), col);
+        assertEquals(1, col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems("a"));
+    }
+
+    @Test
+    public void multiLevelAll() throws Exception{
+        Aggregate ag = new Aggregate("nt:base", of(ni("*"), ni("*/*")));
+        NodeBuilder nb = newNode("nt:base");
+        nb.child("a").child("c");
+        nb.child("b");
+        nb.child("d").child("e").child("f");
+
+        ag.collectAggregates(nb.getNodeState(), col);
+        assertEquals(5, col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems("a", "b", "d", "a/c", "d/e"));
+    }
+
+    @Test
+    public void multiLevelNamed() throws Exception{
+        Aggregate ag = new Aggregate("nt:base", of(ni("a"), ni("d/e")));
+        NodeBuilder nb = newNode("nt:base");
+        nb.child("a").child("c");
+        nb.child("b");
+        nb.child("d").child("e").child("f");
+
+        ag.collectAggregates(nb.getNodeState(), col);
+        assertEquals(2, col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems("a", "d/e"));
+    }
+
+    @Test
+    public void multiLevelTyped() throws Exception{
+        Aggregate ag = new Aggregate("nt:base", of(ni("a"),
+                ni("nt:resource", "d/*/*", false)));
+        NodeBuilder nb = newNode("nt:base");
+        nb.child("a").child("c");
+        nb.child("b");
+        nb.child("d").child("e").child("f").setProperty(JCR_PRIMARYTYPE,"nt:resource");
+        nb.child("d").child("e").child("f2");
+        nb.child("d").child("e2").child("f3").setProperty(JCR_PRIMARYTYPE, "nt:resource");
+
+        ag.collectAggregates(nb.getNodeState(), col);
+        assertEquals(3, col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems("a", "d/e/f", "d/e2/f3"));
+    }
+
+    @Test
+    public void multiLevelNamedSubAll() throws Exception{
+        Aggregate ag = new Aggregate("nt:base", of(ni("a"), ni("d/*/*")));
+        NodeBuilder nb = newNode("nt:base");
+        nb.child("a").child("c");
+        nb.child("b");
+        nb.child("d").child("e").child("f");
+        nb.child("d").child("e").child("f2");
+        nb.child("d").child("e2").child("f3");
+
+        ag.collectAggregates(nb.getNodeState(), col);
+        assertEquals(4, col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems("a", "d/e/f", "d/e/f2", "d/e2/f3"));
+    }
+
+    //~---------------------------------< Node include recursive >
+
+    @Test
+    public void multiAggregateMapping() throws Exception{
+        Aggregate ag = new Aggregate("nt:base", of(ni("*")));
+
+        Aggregate agFile = new Aggregate("nt:file", of(ni("*"), ni("*/*")));
+        mapper.add("nt:file", agFile);
+
+        NodeBuilder nb = newNode("nt:base");
+        nb.child("a").child("c");
+        nb.child("b").setProperty(JCR_PRIMARYTYPE, "nt:file");
+        nb.child("b").child("b1").child("b2");
+        nb.child("c");
+
+        ag.collectAggregates(nb.getNodeState(), col);
+        assertEquals(5, col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems("a", "b", "c", "b/b1", "b/b1/b2"));
+    }
+
+    @Test
+    public void recursionEnabled() throws Exception{
+        Aggregate agFile = new Aggregate("nt:file", of(ni("*")), 5);
+        mapper.add("nt:file", agFile);
+
+        NodeBuilder nb = newNode("nt:file");
+        nb.child("a").child("c");
+        nb.child("b").setProperty(JCR_PRIMARYTYPE, "nt:file");
+        nb.child("b").child("b1").child("b2");
+        nb.child("c");
+
+        agFile.collectAggregates(nb.getNodeState(), col);
+        assertEquals(4, col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems("a", "b", "c", "b/b1"));
+    }
+
+    @Test
+    public void recursionEnabledWithLimitCheck() throws Exception{
+        int limit = 5;
+        Aggregate agFile = new Aggregate("nt:file", of(ni("*")), limit);
+        mapper.add("nt:file", agFile);
+
+        List<String> expectedPaths = Lists.newArrayList();
+        NodeBuilder nb = newNode("nt:file");
+        nb.child("a").child("c");
+
+        String path = "";
+        NodeBuilder fb = nb;
+        for (int i = 0; i < limit + 2; i++){
+            String name = "f "+ i;
+            path = PathUtils.concat(path, name);
+            fb = fb.child(name);
+            fb.setProperty(JCR_PRIMARYTYPE, "nt:file");
+
+            if (i < limit) {
+                expectedPaths.add(path);
+            }
+        }
+        expectedPaths.add("a");
+
+        agFile.collectAggregates(nb.getNodeState(), col);
+        assertEquals(expectedPaths.size(), col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems(toArray(expectedPaths, String.class)));
+    }
+
+    @Test
+    public void includeMatches() throws Exception{
+        Aggregate ag = new Aggregate("nt:base", of(ni(null, "*", true), ni(null, "*/*", true)));
+        assertTrue(ag.hasRelativeNodeInclude("foo"));
+        assertTrue(ag.hasRelativeNodeInclude("foo/bar"));
+        assertFalse(ag.hasRelativeNodeInclude("foo/bar/baz"));
+
+
+        Aggregate ag2 = new Aggregate("nt:base", of(ni(null, "foo", true), ni(null, "foo/*", true)));
+        assertTrue(ag2.hasRelativeNodeInclude("foo"));
+        assertFalse(ag2.hasRelativeNodeInclude("bar"));
+        assertTrue(ag2.hasRelativeNodeInclude("foo/bar"));
+        assertFalse(ag2.hasRelativeNodeInclude("foo/bar/baz"));
+    }
+
+    @Test
+    public void testReaggregate() throws Exception{
+        //Enable relative include for all child nodes of nt:folder
+        //So indexing would create fulltext field for each relative nodes
+        Aggregate agFolder = new Aggregate("nt:folder", of(ni("nt:file", "*", true)));
+
+        Aggregate agFile = new Aggregate("nt:file", of(ni(null, "jcr:content", true)));
+        mapper.add("nt:file", agFile);
+        mapper.add("nt:folder", agFolder);
+
+        NodeBuilder nb = newNode("nt:folder");
+        nb.child("a").child("c");
+        createFile(nb, "b", "hello world");
+        createFile(nb, "c", "hello world");
+
+        agFolder.collectAggregates(nb.getNodeState(), col);
+        assertEquals(4, col.getNodePaths().size());
+        assertThat(col.getNodePaths(), hasItems("b", "c", "b/jcr:content", "c/jcr:content"));
+
+        assertEquals(2, col.nodeResults.get("b/jcr:content").size());
+
+        //Check that a result is provided for relative node 'b'. Actual node provided
+        //is b/jcr:content
+        assertEquals(1, col.getRelativeNodeResults("b/jcr:content", "b").size());
+    }
+
+    private static void createFile(NodeBuilder nb, String fileName, String content){
+        nb.child(fileName).setProperty(JCR_PRIMARYTYPE, "nt:file")
+                .child("jcr:content").setProperty("jcr:data", content.getBytes());
+    }
+
+    //~---------------------------------< Prop Includes >
+
+    @Test
+    public void propOneLevelNamed() throws Exception{
+        NodeBuilder rules = builder.child(INDEX_RULES);
+        rules.child("nt:folder");
+        child(rules, "nt:folder/properties/p1")
+                .setProperty(LuceneIndexConstants.PROP_NAME, "a/p1");
+
+        IndexDefinition defn = new IndexDefinition(root, builder.getNodeState());
+        Aggregate ag = defn.getApplicableIndexingRule("nt:folder").getAggregate();
+
+        NodeBuilder nb = newNode("nt:folder");
+        nb.child("a").setProperty("p1", "foo");
+        nb.child("a").setProperty("p2", "foo");
+        nb.child("b").setProperty("p2", "foo");
+
+        ag.collectAggregates(nb.getNodeState(), col);
+        assertEquals(1, col.getPropPaths().size());
+        assertThat(col.getPropPaths(), hasItems("a/p1"));
+    }
+
+    @Test
+    public void propOneLevelRegex() throws Exception{
+        NodeBuilder rules = builder.child(INDEX_RULES);
+        rules.child("nt:folder");
+        child(rules, "nt:folder/properties/p1")
+                .setProperty(LuceneIndexConstants.PROP_NAME, "a/foo.*")
+                .setProperty(LuceneIndexConstants.PROP_IS_REGEX, true);
+
+        IndexDefinition defn = new IndexDefinition(root, builder.getNodeState());
+        Aggregate ag = defn.getApplicableIndexingRule("nt:folder").getAggregate();
+
+        NodeBuilder nb = newNode("nt:folder");
+        nb.child("a").setProperty("foo1", "foo");
+        nb.child("a").setProperty("foo2", "foo");
+        nb.child("a").setProperty("bar1", "foo");
+        nb.child("b").setProperty("p2", "foo");
+
+        ag.collectAggregates(nb.getNodeState(), col);
+        assertEquals(2, col.getPropPaths().size());
+        assertThat(col.getPropPaths(), hasItems("a/foo1", "a/foo2"));
+    }
+
+    //~---------------------------------< IndexingConfig >
+
+    @Test
+    public void simpleAggregateConfig() throws Exception{
+        NodeBuilder aggregates = builder.child(LuceneIndexConstants.AGGREGATES);
+        NodeBuilder aggFolder = aggregates.child("nt:folder");
+        aggFolder.child("i1").setProperty(LuceneIndexConstants.AGG_PATH, "*");
+
+        IndexDefinition defn = new IndexDefinition(root, builder.getNodeState());
+        Aggregate agg = defn.getAggregate("nt:folder");
+        assertNotNull(agg);
+        assertEquals(1, agg.getIncludes().size());
+    }
+
+    @Test
+    public void aggregateConfig2() throws Exception{
+        NodeBuilder aggregates = builder.child(LuceneIndexConstants.AGGREGATES);
+        NodeBuilder aggFolder = aggregates.child("nt:folder");
+        aggFolder.setProperty(LuceneIndexConstants.AGG_RECURSIVE_LIMIT, 42);
+        aggFolder.child("i1").setProperty(LuceneIndexConstants.AGG_PATH, "*");
+        aggFolder.child("i1").setProperty(LuceneIndexConstants.AGG_PRIMARY_TYPE, "nt:file");
+        aggFolder.child("i1").setProperty(LuceneIndexConstants.AGG_RELATIVE_NODE, true);
+
+        IndexDefinition defn = new IndexDefinition(root, builder.getNodeState());
+        Aggregate agg = defn.getAggregate("nt:folder");
+        assertNotNull(agg);
+        assertEquals(42, agg.reAggregationLimit);
+        assertEquals(1, agg.getIncludes().size());
+        assertEquals("nt:file", ((NodeInclude)agg.getIncludes().get(0)).primaryType);
+        assertTrue(((NodeInclude)agg.getIncludes().get(0)).relativeNode);
+    }
+
+    private static NodeBuilder newNode(String typeName){
+        NodeBuilder builder = EMPTY_NODE.builder();
+        builder.setProperty(JCR_PRIMARYTYPE, typeName);
+        return builder;
+    }
+
+    private static NodeBuilder child(NodeBuilder nb, String path) {
+        for (String name : PathUtils.elements(checkNotNull(path))) {
+            nb = nb.child(name);
+        }
+        return nb;
+    }
+
+    private Aggregate.Include ni(String pattern){
+        return new NodeInclude(mapper, pattern);
+    }
+
+    private Aggregate.Include ni(String type, String pattern, boolean relativeNode){
+        return new NodeInclude(mapper, type, pattern, relativeNode);
+    }
+
+    private static class TestCollector implements Aggregate.ResultCollector {
+        final ListMultimap<String, NodeIncludeResult> nodeResults = ArrayListMultimap.create();
+        final Map<String, PropertyIncludeResult> propResults = newHashMap();
+        @Override
+        public void onResult(NodeIncludeResult result) throws CommitFailedException{
+            nodeResults.put(result.nodePath, result);
+        }
+
+        @Override
+        public void onResult(PropertyIncludeResult result) throws CommitFailedException {
+            propResults.put(result.propertyPath, result);
+
+        }
+
+        public Collection<String> getNodePaths(){
+            return nodeResults.keySet();
+        }
+
+        public Collection<String> getPropPaths(){
+            return propResults.keySet();
+        }
+
+        public void reset(){
+            nodeResults.clear();
+            propResults.clear();
+        }
+
+        public List<NodeIncludeResult> getRelativeNodeResults(String path, String rootIncludePath){
+            List<NodeIncludeResult> result = Lists.newArrayList();
+
+            for (NodeIncludeResult nr : nodeResults.get(path)){
+                if (rootIncludePath.equals(nr.rootIncludePath)){
+                    result.add(nr);
+                }
+            }
+
+            return result;
+        }
+    }
+
+    private static class SimpleMapper implements Aggregate.AggregateMapper {
+        final Map<String, Aggregate> mapping = newHashMap();
+
+        @Override
+        public Aggregate getAggregate(String nodeTypeName) {
+            return mapping.get(nodeTypeName);
+        }
+
+        public void add(String type, Aggregate agg){
+            mapping.put(type, agg);
+        }
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/AggregateTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java?rev=1641771&r1=1641770&r2=1641771&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java Wed Nov 26 08:06:52 2014
@@ -22,7 +22,6 @@ package org.apache.jackrabbit.oak.plugin
 import javax.jcr.PropertyType;
 
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.commons.PathUtils;
@@ -141,25 +140,12 @@ public class IndexDefinitionTest {
     }
 
     @Test
-    public void relativeProperty() throws Exception{
-        builder.setProperty(createProperty(INCLUDE_PROPERTY_NAMES, of("foo" , "foo1/bar"), STRINGS));
-        IndexDefinition idxDefn = new IndexDefinition(root, builder.getNodeState());
-        IndexingRule rule = idxDefn.getApplicableIndexingRule(NT_BASE);
-
-        assertEquals(1, rule.getRelativeProps().size());
-        assertEquals("foo1/bar", Iterables.getFirst(rule.getRelativeProps(), null).propertyPath);
-        assertTrue(idxDefn.hasRelativeProperty("bar"));
-        assertFalse(idxDefn.hasRelativeProperty("foo"));
-    }
-
-    @Test
     public void relativePropertyConfig() throws Exception{
         builder.child(PROP_NODE).child("foo1").child("bar").setProperty(LuceneIndexConstants.PROP_TYPE, PropertyType.TYPENAME_DATE);
         builder.child(PROP_NODE).child("foo2").child("bar2").child("baz").setProperty(LuceneIndexConstants.PROP_TYPE, PropertyType.TYPENAME_LONG);
         builder.setProperty(createProperty(INCLUDE_PROPERTY_NAMES, of("foo", "foo1/bar", "foo2/bar2/baz"), STRINGS));
         IndexDefinition defn = new IndexDefinition(root, builder.getNodeState());
         IndexingRule rule = defn.getApplicableIndexingRule(newTree(newNode("nt:folder")));
-        assertEquals(2, defn.getRelativeProps().size());
         assertNotNull(rule.getConfig("foo1/bar"));
         assertEquals(PropertyType.DATE, rule.getConfig("foo1/bar").getType());
         assertEquals(PropertyType.LONG, rule.getConfig("foo2/bar2/baz").getType());

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java?rev=1641771&r1=1641770&r2=1641771&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java Wed Nov 26 08:06:52 2014
@@ -30,8 +30,8 @@ import org.apache.jackrabbit.oak.query.a
 import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
 import org.apache.jackrabbit.oak.query.fulltext.FullTextParser;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
-import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.lucene.document.Document;
@@ -48,19 +48,18 @@ import static javax.jcr.PropertyType.TYP
 import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
 import static org.apache.jackrabbit.oak.api.Type.STRINGS;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
-import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INCLUDE_PROPERTY_NAMES;
 import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INDEX_DATA_CHILD_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.ORDERED_PROP_NAMES;
 import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.VERSION;
 import static org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.newLuceneIndexDefinition;
 import static org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.newLucenePropertyIndexDefinition;
-import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
 import static org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
 import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
 import static org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT;
 import static org.apache.jackrabbit.oak.spi.query.QueryIndex.OrderEntry;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 public class IndexPlannerTest {
     private NodeState root = INITIAL_CONTENT;
@@ -125,6 +124,19 @@ public class IndexPlannerTest {
         IndexPlanner planner = new IndexPlanner(node, "/foo", filter, Collections.<OrderEntry>emptyList());
         assertNull(planner.getPlan());
     }
+    @Test
+    public void matchingProperty() throws Exception{
+        NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test", of("foo"), "async");
+        IndexNode node = createIndexNode(new IndexDefinition(root, defn.getNodeState()));
+        FilterImpl filter = createFilter("nt:base");
+        filter.restrictProperty("foo", Operator.EQUAL, PropertyValues.newString("bar"));
+        IndexPlanner planner = new IndexPlanner(node, "/foo", filter, Collections.<OrderEntry>emptyList());
+        QueryIndex.IndexPlan plan = planner.getPlan();
+        assertNotNull(plan);
+        assertNotNull(pr(plan));
+        assertTrue(pr(plan).evaluateNonFullTextConstraints());
+    }
+
 
     @Test
     public void worksWithIndexFormatV2Onwards() throws Exception{
@@ -164,4 +176,9 @@ public class IndexPlannerTest {
         writer.close();
         return dir;
     }
+
+    private static IndexPlanner.PlanResult pr(QueryIndex.IndexPlan plan) {
+        return (IndexPlanner.PlanResult) plan.getAttribute(LucenePropertyIndex.ATTR_PLAN_RESULT);
+    }
+
 }

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest.java?rev=1641771&r1=1641770&r2=1641771&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest.java Wed Nov 26 08:06:52 2014
@@ -31,15 +31,17 @@ import org.apache.jackrabbit.oak.Oak;
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.plugins.index.aggregate.AggregateIndexProvider;
 import org.apache.jackrabbit.oak.plugins.index.aggregate.NodeAggregator;
 import org.apache.jackrabbit.oak.plugins.index.aggregate.SimpleNodeAggregator;
 
+import static org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.newNodeAggregator;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.useV2;
 import static org.apache.jackrabbit.oak.plugins.memory.BinaryPropertyState.binaryProperty;
 
 import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
 import org.apache.jackrabbit.oak.query.AbstractQueryTest;
 import org.apache.jackrabbit.oak.spi.commit.Observer;
+import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
 import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
 import org.junit.Test;
 
@@ -51,8 +53,16 @@ public class LuceneIndexAggregationTest 
     protected void createTestIndexNode() throws Exception {
         Tree index = root.getTree("/");
         Tree indexDefn = createTestIndexNode(index, LuceneIndexConstants.TYPE_LUCENE);
-        //TODO Remove compat mode once OAK-2278 resolved
-        indexDefn.setProperty(LuceneIndexConstants.COMPAT_MODE, IndexFormatVersion.V1.getVersion());
+        useV2(indexDefn);
+        //Aggregates
+        newNodeAggregator(indexDefn)
+                .newRuleWithName(NT_FILE, newArrayList(JCR_CONTENT, JCR_CONTENT + "/*"))
+                .newRuleWithName(NT_FOLDER, newArrayList("myFile", "subfolder/subsubfolder/file"));
+
+        //Include all properties
+        Tree props = TestUtil.newRulePropTree(indexDefn, "nt:base");
+        TestUtil.enableForFullText(props, LuceneIndexConstants.REGEX_ALL_PROPS, true);
+
         root.commit();
     }
 
@@ -62,7 +72,7 @@ public class LuceneIndexAggregationTest 
         return new Oak()
                 .with(new InitialContent())
                 .with(new OpenSecurityProvider())
-                .with(AggregateIndexProvider.wrap(provider.with(getNodeAggregator())))
+                .with((QueryIndexProvider)provider.with(getNodeAggregator()))
                 .with((Observer) provider)
                 .with(new LuceneIndexEditorProvider())
                 .createContentRepository();

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest2.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest2.java?rev=1641771&r1=1641770&r2=1641771&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest2.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest2.java Wed Nov 26 08:06:52 2014
@@ -28,6 +28,8 @@ import static org.apache.jackrabbit.JcrC
 import static org.apache.jackrabbit.oak.api.Type.NAME;
 import static org.apache.jackrabbit.oak.api.Type.STRING;
 import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.newNodeAggregator;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.useV2;
 import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
 import static org.junit.Assert.fail;
 
@@ -38,15 +40,16 @@ import java.util.List;
 
 import javax.annotation.Nonnull;
 
+import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.Oak;
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.core.SystemRoot;
-import org.apache.jackrabbit.oak.plugins.index.aggregate.AggregateIndexProvider;
 import org.apache.jackrabbit.oak.plugins.index.aggregate.NodeAggregator;
 import org.apache.jackrabbit.oak.plugins.index.aggregate.SimpleNodeAggregator;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
 import org.apache.jackrabbit.oak.plugins.name.NamespaceEditorProvider;
 import org.apache.jackrabbit.oak.plugins.nodetype.TypeEditorProvider;
 import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
@@ -55,11 +58,13 @@ import org.apache.jackrabbit.oak.query.A
 import org.apache.jackrabbit.oak.spi.commit.CompositeEditorProvider;
 import org.apache.jackrabbit.oak.spi.commit.EditorHook;
 import org.apache.jackrabbit.oak.spi.commit.Observer;
+import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
 import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
 import org.apache.jackrabbit.oak.spi.state.ApplyDiff;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.util.TreeUtil;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -120,7 +125,7 @@ public class LuceneIndexAggregationTest2
 
             })
             .with(new OpenSecurityProvider())
-            .with(AggregateIndexProvider.wrap(provider.with(getNodeAggregator())))
+            .with(((QueryIndexProvider)provider.with(getNodeAggregator())))
             .with((Observer) provider).with(new LuceneIndexEditorProvider())
             .createContentRepository();
     }
@@ -144,7 +149,29 @@ public class LuceneIndexAggregationTest2
     @Override
     protected void createTestIndexNode() throws Exception {
         Tree index = root.getTree("/");
-        createTestIndexNode(index, LuceneIndexConstants.TYPE_LUCENE);
+        Tree indexDefn = createTestIndexNode(index, LuceneIndexConstants.TYPE_LUCENE);
+        useV2(indexDefn);
+        //Aggregates
+        newNodeAggregator(indexDefn)
+                .newRuleWithName(NT_FILE, newArrayList("jcr:content"))
+                .newRuleWithName(NT_TEST_PAGE, newArrayList("jcr:content"))
+                .newRuleWithName(NT_TEST_PAGECONTENT, newArrayList("*", "*/*", "*/*/*", "*/*/*/*"))
+                .newRuleWithName(NT_TEST_ASSET, newArrayList("jcr:content"))
+                .newRuleWithName(
+                        NT_TEST_ASSETCONTENT,
+                        newArrayList("metadata", "renditions", "renditions/original", "comments",
+                                "renditions/original/jcr:content"))
+                .newRuleWithName("rep:User", newArrayList("profile"));
+
+        Tree originalInclude = indexDefn.getChild(LuceneIndexConstants.AGGREGATES)
+                .getChild(NT_TEST_ASSET).addChild("includeOriginal");
+        originalInclude.setProperty(LuceneIndexConstants.AGG_RELATIVE_NODE, true);
+        originalInclude.setProperty(LuceneIndexConstants.AGG_PATH, "jcr:content/renditions/original");
+
+        //Include all properties
+        Tree props = TestUtil.newRulePropTree(indexDefn, "test:Asset");
+        TestUtil.enableForFullText(props, "jcr:content/metadata/format");
+        TestUtil.enableForFullText(props, LuceneIndexConstants.REGEX_ALL_PROPS, true);
         root.commit();
     }
 
@@ -265,7 +292,41 @@ public class LuceneIndexAggregationTest2
         assertQuery(statement, "xpath", expected);
         setTraversalEnabled(true);
     }
-    
+
+    @Test
+    public void indexRelativeNode() throws Exception {
+        setTraversalEnabled(false);
+        final String statement = "//element(*, test:Asset)[ " +
+                "jcr:contains(., 'summer') " +
+                "and jcr:contains(jcr:content/renditions/original, 'fox')" +
+                "and jcr:contains(jcr:content/metadata/@format, 'image') " +
+                "]";
+
+        Tree content = root.getTree("/").addChild("content");
+        List<String> expected = newArrayList();
+
+        Tree metadata = createAssetStructure(content, "tagged");
+        metadata.setProperty("tags", of("namespace:season/summer"), STRINGS);
+        metadata.setProperty("format", "image/jpeg", STRING);
+
+        Tree original = metadata.getParent().addChild("renditions").addChild("original");
+        original.setProperty(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_FILE);
+        original.addChild("jcr:content").setProperty(PropertyStates.createProperty("jcr:data", "fox jumps".getBytes()));
+
+        expected.add("/content/tagged");
+        root.commit();
+
+        assertQuery(statement, "xpath", expected);
+
+        //Update the reaggregated node and with that parent should be get updated
+        Tree originalContent = TreeUtil.getTree(root.getTree("/"), "/content/tagged/jcr:content/renditions/original/jcr:content");
+        originalContent.setProperty(PropertyStates.createProperty("jcr:data", "kiwi jumps".getBytes()));
+        root.commit();
+        assertQuery(statement, "xpath", Collections.<String>emptyList());
+        setTraversalEnabled(true);
+    }
+
+
     /**
      * <p>
      * convenience method that create an "asset" structure like

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorTest.java?rev=1641771&r1=1641770&r2=1641771&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorTest.java Wed Nov 26 08:06:52 2014
@@ -93,11 +93,15 @@ public class LuceneIndexEditorTest {
         tracker.update(indexed);
 
         //system fields starts with ':' so need to be escaped
-        assertEquals("/test", query("\\"+FieldNames.createAnalyzedFieldName("foo")+":fox"));
+        assertEquals("/test", query(escape(FieldNames.createAnalyzedFieldName("foo"))+":fox"));
         assertNull("Non string properties not indexed by default",
                 getPath(NumericRangeQuery.newLongRange("price", 100L, 100L, true, true)));
     }
 
+    private String escape(String name) {
+        return name.replace(":", "\\:");
+    }
+
     @Test
     public void testLuceneWithNonFullText() throws Exception {
         NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java?rev=1641771&r1=1641770&r2=1641771&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java Wed Nov 26 08:06:52 2014
@@ -28,11 +28,13 @@ import org.apache.jackrabbit.oak.query.A
 import org.apache.jackrabbit.oak.spi.commit.Observer;
 import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
 import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import static java.util.Arrays.asList;
 import static junit.framework.Assert.assertEquals;
 import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.useV2;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -46,8 +48,14 @@ public class LuceneIndexQueryTest extend
     protected void createTestIndexNode() throws Exception {
         Tree index = root.getTree("/");
         Tree indexDefn = createTestIndexNode(index, LuceneIndexConstants.TYPE_LUCENE);
-        //TODO Remove compat mode once OAK-2278 resolved
-        indexDefn.setProperty(LuceneIndexConstants.COMPAT_MODE, IndexFormatVersion.V1.getVersion());
+        useV2(indexDefn);
+        indexDefn.setProperty(LuceneIndexConstants.TEST_MODE, true);
+        indexDefn.setProperty(LuceneIndexConstants.EVALUATE_PATH_RESTRICTION, true);
+
+        Tree props = TestUtil.newRulePropTree(indexDefn, "nt:base");
+        TestUtil.enablePropertyIndex(props, "c1/p", false);
+        TestUtil.enableForFullText(props, LuceneIndexConstants.REGEX_ALL_PROPS, true);
+
         root.commit();
     }
 
@@ -67,6 +75,7 @@ public class LuceneIndexQueryTest extend
         test("sql1.txt");
     }
 
+    @Ignore("OAK-2296")
     @Test
     public void sql2() throws Exception {
         test("sql2.txt");

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/TestUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/TestUtil.java?rev=1641771&r1=1641770&r2=1641771&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/TestUtil.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/TestUtil.java Wed Nov 26 08:06:52 2014
@@ -19,7 +19,9 @@
 
 package org.apache.jackrabbit.oak.plugins.index.lucene;
 
+import java.util.List;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -29,6 +31,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 
 public class TestUtil {
+    private static final AtomicInteger COUNTER = new AtomicInteger();
 
     static void useV2(NodeBuilder idxNb) {
         idxNb.setProperty(LuceneIndexConstants.COMPAT_MODE, IndexFormatVersion.V2.getVersion());
@@ -46,4 +49,62 @@ public class TestUtil {
         return nb;
     }
 
+    public static Tree enableForFullText(Tree props, String propName) {
+        return enableForFullText(props, propName, false);
+    }
+
+    public static Tree enableForFullText(Tree props, String propName,  boolean regex) {
+        Tree prop = props.addChild(unique("prop"));
+        prop.setProperty(LuceneIndexConstants.PROP_NAME, propName);
+        prop.setProperty(LuceneIndexConstants.PROP_PROPERTY_INDEX, true);
+        prop.setProperty(LuceneIndexConstants.PROP_IS_REGEX, regex);
+        prop.setProperty(LuceneIndexConstants.PROP_NODE_SCOPE_INDEX, true);
+        prop.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
+        prop.setProperty(LuceneIndexConstants.PROP_USE_IN_EXCERPT, true);
+        return prop;
+    }
+
+    public static Tree enablePropertyIndex(Tree props, String propName,  boolean regex) {
+        Tree prop = props.addChild(unique("prop"));
+        prop.setProperty(LuceneIndexConstants.PROP_NAME, propName);
+        prop.setProperty(LuceneIndexConstants.PROP_PROPERTY_INDEX, true);
+        prop.setProperty(LuceneIndexConstants.PROP_IS_REGEX, regex);
+        prop.setProperty(LuceneIndexConstants.PROP_NODE_SCOPE_INDEX, false);
+        prop.setProperty(LuceneIndexConstants.PROP_ANALYZED, false);
+        return prop;
+    }
+
+    public static AggregatorBuilder newNodeAggregator(Tree indexDefn){
+        return new AggregatorBuilder(indexDefn);
+    }
+
+    public static Tree newRulePropTree(Tree indexDefn, String typeName){
+        Tree rules = indexDefn.addChild(LuceneIndexConstants.INDEX_RULES);
+        rules.setOrderableChildren(true);
+        Tree rule = rules.addChild(typeName);
+        Tree props = rule.addChild(LuceneIndexConstants.PROP_NODE);
+        props.setOrderableChildren(true);
+        return props;
+    }
+
+    static class AggregatorBuilder {
+        private final Tree aggs;
+
+        private AggregatorBuilder(Tree indexDefn) {
+            this.aggs = indexDefn.addChild(LuceneIndexConstants.AGGREGATES);
+        }
+
+        AggregatorBuilder newRuleWithName(String primaryType,
+                                          List<String> includes){
+            Tree agg = aggs.addChild(primaryType);
+            for (String include : includes){
+                agg.addChild(unique("include")).setProperty(LuceneIndexConstants.AGG_PATH, include);
+            }
+            return this;
+        }
+    }
+
+    private static String unique(String name){
+        return name + COUNTER.getAndIncrement();
+    }
 }