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 2017/10/03 05:07:44 UTC

svn commit: r1810636 - in /jackrabbit/oak/trunk/oak-lucene/src: main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/ test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/

Author: chetanm
Date: Tue Oct  3 05:07:44 2017
New Revision: 1810636

URL: http://svn.apache.org/viewvc?rev=1810636&view=rev
Log:
OAK-6535 - Synchronous Lucene Property Indexes

Enable lookup support based on property restrictions

Added:
    jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexLookupTest.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexLookup.java

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexLookup.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexLookup.java?rev=1810636&r1=1810635&r2=1810636&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexLookup.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexLookup.java Tue Oct  3 05:07:44 2017
@@ -25,6 +25,8 @@ import java.util.Set;
 import com.google.common.collect.Iterables;
 import org.apache.jackrabbit.oak.api.PropertyValue;
 import org.apache.jackrabbit.oak.plugins.index.lucene.PropertyDefinition;
+import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexUtil;
+import org.apache.jackrabbit.oak.plugins.index.property.ValuePatternUtil;
 import org.apache.jackrabbit.oak.plugins.index.property.strategy.ContentMirrorStoreStrategy;
 import org.apache.jackrabbit.oak.plugins.index.property.strategy.UniqueEntryStoreStrategy;
 import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -45,8 +47,23 @@ public class HybridPropertyIndexLookup {
     }
 
     public Iterable<String> query(Filter filter, PropertyDefinition pd,
+                                  String propertyName, Filter.PropertyRestriction restriction) {
+        //The propertyName may differ from name in restriction. For e.g. for relative properties
+        //the restriction property name can be 'jcr:content/status' while the index has indexed
+        //for 'status'
+
+        Set<String> values = ValuePatternUtil.getAllValues(restriction);
+        Set<String> encodedValues = PropertyIndexUtil.encode(values);
+        return query(filter, pd, propertyName, encodedValues);
+    }
+
+    public Iterable<String> query(Filter filter, PropertyDefinition pd,
                                   String propertyName, PropertyValue value) {
+        return query(filter, pd, propertyName, encode(value, pd.valuePattern));
+    }
 
+    private Iterable<String> query(Filter filter, PropertyDefinition pd,
+                                  String propertyName, Set<String> encodedValues) {
         String propIdxNodeName = HybridPropertyIndexUtil.getNodeName(propertyName);
         NodeState propIndexRootNode = indexState.getChildNode(PROPERTY_INDEX);
         NodeState propIndexNode = propIndexRootNode.getChildNode(propIdxNodeName);
@@ -55,13 +72,11 @@ public class HybridPropertyIndexLookup {
         }
 
         //TODO Check for non root indexes
-
         String indexName = indexPath + "(" + propertyName + ")";
-        Set<String> values = encode(value, pd.valuePattern);
         if (pd.unique) {
-            return queryUnique(filter, indexName, propIndexRootNode, propIdxNodeName, values);
+            return queryUnique(filter, indexName, propIndexRootNode, propIdxNodeName, encodedValues);
         } else {
-            return querySimple(filter, indexName, propIndexNode, values);
+            return querySimple(filter, indexName, propIndexNode, encodedValues);
         }
     }
 

Added: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexLookupTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexLookupTest.java?rev=1810636&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexLookupTest.java (added)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexLookupTest.java Tue Oct  3 05:07:44 2017
@@ -0,0 +1,139 @@
+/*
+ * 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.property;
+
+import java.util.List;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterators;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.index.Cursors;
+import org.apache.jackrabbit.oak.plugins.index.lucene.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.lucene.PropertyDefinition;
+import org.apache.jackrabbit.oak.plugins.index.lucene.util.IndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.query.NodeStateNodeTypeInfoProvider;
+import org.apache.jackrabbit.oak.query.QueryEngineSettings;
+import org.apache.jackrabbit.oak.query.ast.NodeTypeInfo;
+import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
+import org.apache.jackrabbit.oak.query.ast.Operator;
+import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.query.Cursor;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Test;
+
+import static org.apache.jackrabbit.oak.InitialContent.INITIAL_CONTENT;
+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.memory.PropertyValues.newString;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.empty;
+import static org.junit.Assert.assertThat;
+
+public class HybridPropertyIndexLookupTest {
+    private NodeState root = INITIAL_CONTENT;
+    private NodeBuilder builder = EMPTY_NODE.builder();
+    private IndexDefinitionBuilder defnb = new IndexDefinitionBuilder();
+    private String indexPath  = "/oak:index/foo";
+    private PropertyIndexUpdateCallback callback = new PropertyIndexUpdateCallback(indexPath, builder);
+
+    @Test
+    public void simplePropertyRestriction() throws Exception{
+        defnb.indexRule("nt:base").property("foo").sync();
+
+        propertyUpdated("/a", "foo", "bar");
+
+        FilterImpl f = createFilter();
+        f.restrictProperty("foo", Operator.EQUAL, newString("bar"));
+
+        assertThat(query(f, "foo"), containsInAnyOrder("/a"));
+    }
+
+    @Test
+    public void valuePattern() throws Exception{
+        defnb.indexRule("nt:base").property("foo").sync().valuePattern("(a.*|b)");
+
+        propertyUpdated("/a", "foo", "a");
+        propertyUpdated("/a1", "foo", "a1");
+        propertyUpdated("/b", "foo", "b");
+        propertyUpdated("/c", "foo", "c");
+
+        assertThat(query("foo", "a"), containsInAnyOrder("/a"));
+        assertThat(query("foo", "a1"), containsInAnyOrder("/a1"));
+        assertThat(query("foo", "b"), containsInAnyOrder("/b"));
+
+        // c should not be found as its excluded
+        assertThat(query("foo", "c"), empty());
+    }
+
+    @Test
+    public void relativeProperty() throws Exception{
+        defnb.indexRule("nt:base").property("foo").sync();
+
+        propertyUpdated("/a", "foo", "bar");
+
+        FilterImpl f = createFilter();
+        f.restrictProperty("jcr:content/foo", Operator.EQUAL, newString("bar"));
+
+        assertThat(query(f, "foo", "jcr:content/foo"), containsInAnyOrder("/a"));
+    }
+
+    private void propertyUpdated(String nodePath, String propertyRelativeName, String value){
+        callback.propertyUpdated(nodePath, propertyRelativeName, pd(propertyRelativeName),
+                null, createProperty(PathUtils.getName(propertyRelativeName), value));
+    }
+
+    private List<String> query(String propertyName, String value) {
+        FilterImpl f = createFilter();
+        f.restrictProperty(propertyName, Operator.EQUAL, newString(value));
+        return query(f, propertyName);
+    }
+
+    private List<String> query(Filter filter, String propertyName) {
+        return query(filter, propertyName, propertyName);
+    }
+
+    private List<String> query(Filter filter, String propertyName, String propertyRestrictionName) {
+        HybridPropertyIndexLookup lookup = new HybridPropertyIndexLookup(indexPath, builder.getNodeState());
+        Iterable<String> paths = lookup.query(filter, pd(propertyName), propertyName,
+                filter.getPropertyRestriction(propertyRestrictionName));
+        Cursor c = Cursors.newPathCursor(paths, new QueryEngineSettings());
+        return ImmutableList.copyOf(Iterators.transform(c, r -> r.getPath()));
+    }
+
+    private PropertyDefinition pd(String propName){
+        IndexDefinition defn = new IndexDefinition(root, defnb.build(), indexPath);
+        return defn.getApplicableIndexingRule("nt:base").getConfig(propName);
+    }
+
+    private FilterImpl createFilter() {
+        return createFilter(root, "nt:base");
+    }
+
+    private FilterImpl createFilter(NodeState root, String nodeTypeName) {
+        NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(root);
+        NodeTypeInfo type = nodeTypes.getNodeTypeInfo(nodeTypeName);
+        SelectorImpl selector = new SelectorImpl(type, nodeTypeName);
+        return new FilterImpl(selector, "SELECT * FROM [" + nodeTypeName + "]", new QueryEngineSettings());
+    }
+
+}
\ No newline at end of file

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