diff --git oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
index 941cb94..af7dc25 100644
--- oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
+++ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
@@ -19,6 +19,7 @@
 
 package org.apache.jackrabbit.oak.plugins.index.lucene;
 
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
@@ -29,8 +30,6 @@ import javax.jcr.PropertyType;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
 import com.google.common.primitives.Ints;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
@@ -40,6 +39,8 @@ import org.apache.lucene.codecs.Codec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static com.google.common.collect.Maps.newHashMap;
+import static com.google.common.collect.Sets.newHashSet;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.DECLARING_NODE_TYPES;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ENTRY_COUNT_PROPERTY_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_COUNT;
@@ -89,6 +90,10 @@ class IndexDefinition {
 
     private final Codec codec;
 
+    private final Map<String,RelativeProperty> relativeProps;
+
+    private final Set<String> relativePropNames;
+
     /**
      * Defines the maximum estimated entry count configured.
      * Defaults to {#DEFAULT_ENTRY_COUNT}
@@ -122,15 +127,9 @@ class IndexDefinition {
         this.fullTextEnabled = getOptionalValue(defn, FULL_TEXT_ENABLED, true);
         //Storage is disabled for non full text indexes
         this.storageEnabled = this.fullTextEnabled && getOptionalValue(defn, EXPERIMENTAL_STORAGE, true);
-
-        Map<String, PropertyDefinition> propDefns = Maps.newHashMap();
-        NodeBuilder propNode = defn.getChildNode(LuceneIndexConstants.PROP_NODE);
-        for(String propName : Iterables.concat(includes, orderedProps)){
-            if(propNode.hasChildNode(propName)){
-                propDefns.put(propName, new PropertyDefinition(this, propName, propNode.child(propName)));
-            }
-        }
-        this.propDefns = ImmutableMap.copyOf(propDefns);
+        this.relativeProps = collectRelativeProps(Iterables.concat(includes, orderedProps));
+        this.propDefns = collectPropertyDefns(defn);
+        this.relativePropNames = collectRelPropertyNames(this.relativeProps.values());
 
         String functionName = getOptionalValue(defn, LuceneIndexConstants.FUNC_NAME, null);
         this.funcName = functionName != null ? "native*" + functionName : null;
@@ -237,8 +236,62 @@ class IndexDefinition {
         return entryCount;
     }
 
+    public Collection<RelativeProperty> getRelativeProps() {
+        return relativeProps.values();
+    }
+
+    public void collectRelPropsForName(String name, Collection<RelativeProperty> relProps){
+        if(hasRelativeProperty(name)){
+            for(RelativeProperty rp : relativeProps.values()){
+                if(rp.name.equals(name)){
+                    relProps.add(rp);
+                }
+            }
+        }
+    }
+
+    boolean hasRelativeProperty(String name) {
+        return relativePropNames.contains(name);
+    }
+
     //~------------------------------------------< Internal >
 
+    private Map<String, RelativeProperty> collectRelativeProps(Iterable<String> propNames) {
+        Map<String, RelativeProperty> relProps = newHashMap();
+        for (String propName : propNames) {
+            if (RelativeProperty.isRelativeProperty(propName)) {
+                relProps.put(propName, new RelativeProperty(propName));
+            }
+        }
+        return ImmutableMap.copyOf(relProps);
+    }
+
+    private Map<String, PropertyDefinition> collectPropertyDefns(NodeBuilder defn) {
+        Map<String, PropertyDefinition> propDefns = newHashMap();
+        NodeBuilder propNode = defn.getChildNode(LuceneIndexConstants.PROP_NODE);
+        for (String propName : Iterables.concat(includes, orderedProps)) {
+            NodeBuilder propDefnNode;
+            if (relativeProps.containsKey(propName)) {
+                propDefnNode = relativeProps.get(propName).getPropDefnNode(propNode);
+            } else {
+                propDefnNode = propNode.getChildNode(propName);
+            }
+
+            if (propDefnNode.exists()) {
+                propDefns.put(propName, new PropertyDefinition(this, propName, propDefnNode));
+            }
+        }
+        return ImmutableMap.copyOf(propDefns);
+    }
+
+    private Set<String> collectRelPropertyNames(Collection<RelativeProperty> props) {
+        Set<String> propNames = newHashSet();
+        for (RelativeProperty prop : props){
+            propNames.add(prop.name);
+        }
+        return ImmutableSet.copyOf(propNames);
+    }
+
     private Codec createCodec() {
         String codecName = getOptionalValue(definition, LuceneIndexConstants.CODEC_NAME, null);
         Codec codec = null;
@@ -271,10 +324,10 @@ class IndexDefinition {
     }
 
     private static Set<String> toLowerCase(Set<String> values){
-        Set<String> result = Sets.newHashSet();
+        Set<String> result = newHashSet();
         for(String val : values){
             result.add(val.toLowerCase());
         }
-        return Collections.unmodifiableSet(result);
+        return ImmutableSet.copyOf(result);
     }
 }
diff --git oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
index 157245e..4b0c012 100644
--- oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
+++ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
@@ -31,6 +31,7 @@ import java.util.List;
 
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
+import com.google.common.collect.Lists;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -89,6 +90,8 @@ public class LuceneIndexEditor implements IndexEditor {
 
     private final Predicate<NodeState> typePredicate;
 
+    private List<RelativeProperty> changedRelativeProps;
+
     LuceneIndexEditor(NodeState root, NodeBuilder definition, Analyzer analyzer,
         IndexUpdateCallback updateCallback) throws CommitFailedException {
         this.parent = null;
@@ -141,6 +144,10 @@ public class LuceneIndexEditor implements IndexEditor {
             }
         }
 
+        if (changedRelativeProps != null) {
+            markParentsOnRelPropChange();
+        }
+
         if (parent == null) {
             try {
                 context.closeWriter();
@@ -156,17 +163,20 @@ public class LuceneIndexEditor implements IndexEditor {
 
     @Override
     public void propertyAdded(PropertyState after) {
-        propertiesChanged = true;
+        markPropertiesChanged();
+        checkForRelativePropertyChange(after.getName());
     }
 
     @Override
     public void propertyChanged(PropertyState before, PropertyState after) {
-        propertiesChanged = true;
+        markPropertiesChanged();
+        checkForRelativePropertyChange(before.getName());
     }
 
     @Override
     public void propertyDeleted(PropertyState before) {
-        propertiesChanged = true;
+        markPropertiesChanged();
+        checkForRelativePropertyChange(before.getName());
     }
 
     @Override
@@ -237,7 +247,7 @@ public class LuceneIndexEditor implements IndexEditor {
             }
 
             if (context.getDefinition().isOrdered(pname)) {
-                dirty |= addTypedOrderedFields(fields, property);
+                dirty |= addTypedOrderedFields(fields, property, pname);
             }
 
             if (context.includeProperty(pname)) {
@@ -255,6 +265,8 @@ public class LuceneIndexEditor implements IndexEditor {
             }
         }
 
+        dirty |= indexRelativeProperties(path, fields, state);
+
         if (isUpdate && !dirty) {
             // updated the state but had no relevant changes
             return null;
@@ -288,7 +300,7 @@ public class LuceneIndexEditor implements IndexEditor {
             return true;
         } else if(!context.isFullTextEnabled()
                 && FieldFactory.canCreateTypedField(property.getType())){
-            return addTypedFields(fields, property);
+            return addTypedFields(fields, property, pname);
         } else {
             boolean dirty = false;
             for (String value : property.getValue(Type.STRINGS)) {
@@ -305,21 +317,20 @@ public class LuceneIndexEditor implements IndexEditor {
         }
     }
 
-    private boolean addTypedFields(List<Field> fields, PropertyState property) throws CommitFailedException {
+    private boolean addTypedFields(List<Field> fields, PropertyState property, String pname) throws CommitFailedException {
         int tag = property.getType().tag();
-        String name = property.getName();
         boolean fieldAdded = false;
         for (int i = 0; i < property.count(); i++) {
             Field f = null;
             if (tag == Type.LONG.tag()) {
-                f = new LongField(name, property.getValue(Type.LONG, i), Field.Store.NO);
+                f = new LongField(pname, property.getValue(Type.LONG, i), Field.Store.NO);
             } else if (tag == Type.DATE.tag()) {
                 String date = property.getValue(Type.DATE, i);
-                f = new LongField(name, FieldFactory.dateToLong(date), Field.Store.NO);
+                f = new LongField(pname, FieldFactory.dateToLong(date), Field.Store.NO);
             } else if (tag == Type.DOUBLE.tag()) {
-                f = new DoubleField(name, property.getValue(Type.DOUBLE, i), Field.Store.NO);
+                f = new DoubleField(pname, property.getValue(Type.DOUBLE, i), Field.Store.NO);
             } else if (tag == Type.BOOLEAN.tag()) {
-                f = new StringField(name, property.getValue(Type.BOOLEAN, i).toString(), Field.Store.NO);
+                f = new StringField(pname, property.getValue(Type.BOOLEAN, i).toString(), Field.Store.NO);
             }
 
             if (f != null) {
@@ -331,10 +342,10 @@ public class LuceneIndexEditor implements IndexEditor {
         return fieldAdded;
     }
 
-    private boolean addTypedOrderedFields(List<Field> fields, PropertyState property) throws CommitFailedException {
+    private boolean addTypedOrderedFields(List<Field> fields, PropertyState property, String pname) throws CommitFailedException {
         int tag = property.getType().tag();
 
-        int idxDefinedTag = getIndexDefinitionType(property);
+        int idxDefinedTag = getIndexDefinitionType(pname);
         // Try converting type to the defined type in the index definition
         if (tag != idxDefinedTag) {
             log.debug(
@@ -345,7 +356,7 @@ public class LuceneIndexEditor implements IndexEditor {
             tag = idxDefinedTag;
         }
 
-        String name = FieldNames.createDocValFieldName(property.getName());
+        String name = FieldNames.createDocValFieldName(pname);
         boolean fieldAdded = false;
         for (int i = 0; i < property.count(); i++) {
             Field f = null;
@@ -376,20 +387,23 @@ public class LuceneIndexEditor implements IndexEditor {
                 log.warn(
                     "Ignoring ordered property. Could not convert property {} of type {} to type " +
                         "{} for path {}",
-                    property, Type.fromTag(property.getType().tag(), false),
+                    pname, Type.fromTag(property.getType().tag(), false),
                     Type.fromTag(tag, false), getPath(), e);
             }
         }
         return fieldAdded;
     }
 
-    private int getIndexDefinitionType(PropertyState property) {
-        int idxDefinedTag =
-            context.getDefinition().getPropDefn(property.getName()).getPropertyType();
-        if (idxDefinedTag == Type.UNDEFINED.tag()) {
-            idxDefinedTag = Type.STRING.tag();
+    private int getIndexDefinitionType(String pname) {
+        int type = Type.UNDEFINED.tag();
+        if (context.getDefinition().hasPropertyDefinition(pname)) {
+            type = context.getDefinition().getPropDefn(pname).getPropertyType();
         }
-        return idxDefinedTag;
+        if (type == Type.UNDEFINED.tag()) {
+            //If no explicit type is defined we assume it to be string
+            type = Type.STRING.tag();
+        }
+        return type;
     }
 
     private static boolean isVisible(String name) {
@@ -417,6 +431,60 @@ public class LuceneIndexEditor implements IndexEditor {
         return fields;
     }
 
+    private boolean indexRelativeProperties(String path, List<Field> fields, NodeState state) throws CommitFailedException {
+        IndexDefinition defn = context.getDefinition();
+        boolean dirty = false;
+        for (RelativeProperty rp : defn.getRelativeProps()){
+            String pname = rp.propertyPath;
+
+            PropertyState property = rp.getProperty(state);
+
+            if (property == null){
+                continue;
+            }
+
+            if (defn.isOrdered(pname)) {
+                dirty |= addTypedOrderedFields(fields, property, pname);
+            }
+
+            dirty |= indexProperty(path, fields, state, property, pname);
+        }
+        return dirty;
+    }
+
+    private void checkForRelativePropertyChange(String name) {
+        if (context.getDefinition().hasRelativeProperty(name)) {
+            context.getDefinition().collectRelPropsForName(name, getChangedRelProps());
+        }
+    }
+
+    private void markParentsOnRelPropChange() {
+        for (RelativeProperty rp : changedRelativeProps){
+            LuceneIndexEditor p = parent;
+            for (String parentName : rp.ancestors){
+                if (p == null || !p.name.equals(parentName)) {
+                    break;
+                }
+                p = p.parent;
+            }
+
+            if (p != null){
+                p.markPropertiesChanged();
+            }
+        }
+    }
+
+    private List<RelativeProperty> getChangedRelProps(){
+        if (changedRelativeProps == null) {
+            changedRelativeProps = Lists.newArrayList();
+        }
+        return changedRelativeProps;
+    }
+
+    private void markPropertiesChanged() {
+        propertiesChanged = true;
+    }
+
     private String parseStringValue(Blob v, Metadata metadata, String path) {
         WriteOutContentHandler handler = new WriteOutContentHandler();
         try {
diff --git oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
index af86699..7ebccab 100644
--- oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
+++ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
@@ -843,10 +843,6 @@ public class LucenePropertyIndex implements AdvancedQueryIndex, QueryIndex {
     private static boolean isExcludedProperty(PropertyRestriction pr,
             IndexDefinition definition) {
         String name = pr.propertyName;
-        if (name.contains("/")) {
-            // lucene cannot handle child-level property restrictions
-            return true;
-        }
 
         boolean includeProperty = definition.includeProperty(name);
         // check name
diff --git oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/RelativeProperty.java oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/RelativeProperty.java
new file mode 100644
index 0000000..c4bd768
--- /dev/null
+++ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/RelativeProperty.java
@@ -0,0 +1,102 @@
+/*
+ * 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 javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+import static com.google.common.collect.ImmutableList.copyOf;
+import static com.google.common.collect.Iterables.toArray;
+import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
+import static org.apache.jackrabbit.oak.commons.PathUtils.isAbsolute;
+
+class RelativeProperty {
+    final String propertyPath;
+    final String parentPath;
+    final String name;
+    /**
+     * Stores the parent path element in reverse order
+     * parentPath -> foo/bar/baz -> [baz, bar, foo]
+     */
+    final String[] ancestors;
+
+    public static boolean isRelativeProperty(String propertyName){
+        return !isAbsolute(propertyName) && PathUtils.getNextSlash(propertyName, 0) > 0;
+    }
+
+    public RelativeProperty(String propertyPath){
+        this.propertyPath = propertyPath;
+        name = PathUtils.getName(propertyPath);
+        parentPath = PathUtils.getParentPath(propertyPath);
+        ancestors = computeAncestors(parentPath);
+    }
+
+    @Nonnull
+    public NodeBuilder getPropDefnNode(NodeBuilder propNode) {
+        NodeBuilder result = propNode;
+        for (String name : elements(parentPath)){
+            result = result.getChildNode(name);
+        }
+        return result;
+    }
+
+    @CheckForNull
+    public PropertyState getProperty(NodeState state) {
+        NodeState node = state;
+        for (String name : elements(parentPath)){
+            node = node.getChildNode(name);
+            if (!node.exists()){
+                return null;
+            }
+        }
+        return node.exists() ? node.getProperty(name) : null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        RelativeProperty that = (RelativeProperty) o;
+
+        if (!propertyPath.equals(that.propertyPath)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return propertyPath.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return propertyPath;
+    }
+
+    private String[] computeAncestors(String parentPath) {
+        return toArray(copyOf(elements(parentPath)).reverse(), String.class);
+    }
+}
diff --git oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java
index f4cadf6..707a39a 100644
--- oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java
+++ oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java
@@ -21,6 +21,7 @@ package org.apache.jackrabbit.oak.plugins.index.lucene;
 
 import javax.jcr.PropertyType;
 
+import com.google.common.collect.Iterables;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.lucene.codecs.Codec;
@@ -108,5 +109,39 @@ public class IndexDefinitionTest {
         assertEquals(simple.getName(), defn.getCodec().getName());
     }
 
+    @Test
+    public void relativeProperty() throws Exception{
+        builder.setProperty(createProperty(INCLUDE_PROPERTY_NAMES, of("foo" , "foo1/bar"), STRINGS));
+        IndexDefinition defn = new IndexDefinition(builder);
+
+        assertEquals(1, defn.getRelativeProps().size());
+        assertEquals(new RelativeProperty("foo1/bar"), Iterables.getFirst(defn.getRelativeProps(), null));
+        assertTrue(defn.hasRelativeProperty("bar"));
+        assertFalse(defn.hasRelativeProperty("foo"));
+    }
+
+    @Test
+    public void relativePropertyConfig() throws Exception{
+        builder.child(PROP_NODE).child("foo1").setProperty(LuceneIndexConstants.PROP_TYPE, PropertyType.TYPENAME_DATE);
+        builder.child(PROP_NODE).child("foo2").child("bar2").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(builder);
+
+        assertEquals(2, defn.getRelativeProps().size());
+        assertNull(defn.getPropDefn("foo"));
+        assertNotNull(defn.getPropDefn("foo1/bar"));
+        assertEquals(PropertyType.DATE, defn.getPropDefn("foo1/bar").getPropertyType());
+        assertEquals(PropertyType.LONG, defn.getPropDefn("foo2/bar2/baz").getPropertyType());
+    }
+
+    @Test
+    public void bool() throws Exception{
+        boolean dirty = true;
+        dirty |= false;
+//        dirty |= true;
+        dirty |= false;
+        System.out.println(dirty);
+    }
+
 
 }
diff --git oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorTest.java oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorTest.java
index 5edec70..20b138e 100644
--- oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorTest.java
+++ oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorTest.java
@@ -153,6 +153,44 @@ public class LuceneIndexEditorTest {
         assertEquals(2, getSearcher().getIndexReader().numDocs());
     }
 
+    @Test
+    public void testLuceneWithRelativeProperty() throws Exception {
+        NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
+        NodeBuilder nb = newLuceneIndexDefinition(index, "lucene",
+                of(TYPENAME_STRING));
+        nb.setProperty(LuceneIndexConstants.FULL_TEXT_ENABLED, false);
+        nb.setProperty(createProperty(INCLUDE_PROPERTY_NAMES, of("foo", "jcr:content/mime",
+                "jcr:content/metadata/type"), STRINGS));
+
+        NodeState before = builder.getNodeState();
+        builder.child("test").setProperty("foo", "fox is jumping");
+        builder.child("test").child("jcr:content").setProperty("mime", "text");
+        builder.child("test").child("jcr:content").child("metadata").setProperty("type", "image");
+        builder.child("jcr:content").setProperty("count", "text");
+        builder.child("jcr:content").child("boom").child("metadata").setProperty("type", "image");
+        NodeState after = builder.getNodeState();
+
+        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+        tracker.update(indexed);
+
+        assertEquals(1, getSearcher().getIndexReader().numDocs());
+
+        assertEquals("/test", getPath(new TermQuery(new Term("foo", "fox is jumping"))));
+        assertEquals("/test", getPath(new TermQuery(new Term("jcr:content/mime", "text"))));
+        assertEquals("/test", getPath(new TermQuery(new Term("jcr:content/metadata/type", "image"))));
+        assertNull("bar must NOT be indexed", getPath(new TermQuery(new Term("count", "text"))));
+
+        releaseIndexNode();
+        before = indexed;
+        builder = before.builder();
+        builder.child("test").child("jcr:content").setProperty("mime", "pdf");
+        after = builder.getNodeState();
+        indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+        tracker.update(indexed);
+
+        assertEquals("/test", getPath(new TermQuery(new Term("jcr:content/mime", "pdf"))));
+    }
+
     //@Test
     public void checkLuceneIndexFileUpdates() throws Exception{
         NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
diff --git oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
index 5cdac07..ac61da6 100644
--- oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
+++ oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
@@ -378,6 +378,20 @@ public class LucenePropertyIndexTest extends AbstractQueryTest {
     }
 
     @Test
+    public void testWithRelativeProperty() throws Exception{
+        Tree parent = root.getTree("/");
+        Tree idx = createIndex(parent, "test1", of("b/propa", "propb"));
+        root.commit();
+
+        Tree test = parent.addChild("test2");
+        test.addChild("a").addChild("b").setProperty("propa", "a");
+        root.commit();
+
+        assertQuery("select [jcr:path] from [nt:base] as s where [b/propa] = 'a'", asList("/test2/a"));
+
+    }
+
+    @Test
     public void indexDefinitionBelowRoot() throws Exception {
         Tree parent = root.getTree("/").addChild("test");
         Tree idx = createIndex(parent, "test1", of("propa", "propb"));
diff --git oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/RelativePropertyTest.java oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/RelativePropertyTest.java
new file mode 100644
index 0000000..400a5a3
--- /dev/null
+++ oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/RelativePropertyTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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 org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class RelativePropertyTest {
+
+    @Test
+    public void relativeProperty() throws Exception{
+        assertTrue(RelativeProperty.isRelativeProperty("foo/bar"));
+        assertTrue(RelativeProperty.isRelativeProperty("foo/bar/baz"));
+        assertFalse(RelativeProperty.isRelativeProperty("/foo/bar/baz"));
+        assertFalse(RelativeProperty.isRelativeProperty("/"));
+        assertFalse(RelativeProperty.isRelativeProperty(""));
+    }
+
+    @Test
+    public void ancesstors() throws Exception{
+        RelativeProperty rp = new RelativeProperty("foo/bar/baz/boom");
+        assertArrayEquals(new String[] {"baz", "bar", "foo"}, rp.ancestors);
+    }
+}
