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 am...@apache.org on 2014/10/28 07:47:04 UTC
svn commit: r1634792 - in /jackrabbit/oak/trunk/oak-lucene/src:
main/java/org/apache/jackrabbit/oak/plugins/index/lucene/
test/java/org/apache/jackrabbit/oak/plugins/index/lucene/
Author: amitj
Date: Tue Oct 28 06:47:04 2014
New Revision: 1634792
URL: http://svn.apache.org/r1634792
Log:
OAK-2198 - Add support for declaringNodeTypes to only index node with specific types
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java?rev=1634792&r1=1634791&r2=1634792&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java Tue Oct 28 06:47:04 2014
@@ -40,6 +40,7 @@ import org.apache.lucene.codecs.Codec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+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;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.BLOB_SIZE;
@@ -72,6 +73,8 @@ public class IndexDefinition {
private final Set<String> orderedProps;
+ private final Set<String> declaringNodeTypes;
+
private final boolean fullTextEnabled;
private final boolean storageEnabled;
@@ -112,6 +115,8 @@ public class IndexDefinition {
this.excludes = toLowerCase(getMultiProperty(defn, EXCLUDE_PROPERTY_NAMES));
this.includes = getMultiProperty(defn, INCLUDE_PROPERTY_NAMES);
this.orderedProps = getMultiProperty(defn, ORDERED_PROP_NAMES);
+ this.declaringNodeTypes = getMultiProperty(defn, DECLARING_NODE_TYPES);
+
this.blobSize = getOptionalValue(defn, BLOB_SIZE, DEFAULT_BLOB_SIZE);
this.fullTextEnabled = getOptionalValue(defn, FULL_TEXT_ENABLED, true);
@@ -169,6 +174,9 @@ public class IndexDefinition {
return propertyTypes;
}
+ public Set<String> getDeclaringNodeTypes() {
+ return declaringNodeTypes;
+ }
/**
* Checks if a given property should be stored in the lucene index or not
*/
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java?rev=1634792&r1=1634791&r2=1634792&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java Tue Oct 28 06:47:04 2014
@@ -21,9 +21,11 @@ package org.apache.jackrabbit.oak.plugin
import java.util.Collections;
import java.util.List;
+import java.util.Set;
import javax.annotation.CheckForNull;
+import com.google.common.collect.Sets;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.query.fulltext.FullTextExpression;
import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -88,19 +90,40 @@ public class IndexPlanner {
//TODO Need a way to have better cost estimate to indicate that
//this index can evaluate more propertyRestrictions natively (if more props are indexed)
//For now we reduce cost per entry
+ int costPerEntryFactor = indexedProps.size();
+
+ // Restrict matching index when declaringNodeTypes declared
+ Set<String> supertypes = getSuperTypes(filter);
+ if (!defn.getDeclaringNodeTypes().isEmpty()) {
+ if ((supertypes != null) && !Sets
+ .intersection(defn.getDeclaringNodeTypes(), supertypes).isEmpty()) {
+ // Reduce cost per entry by a small factor because number of nodes would be less
+ costPerEntryFactor += 1;
+ } else {
+ return null;
+ }
+ }
+ //this index can evaluate more propertyRestrictions natively (if more props are indexed)
+ //For now we reduce cost per entry
IndexPlan.Builder plan = defaultPlan();
if (plan != null) {
- return plan.setCostPerEntry(1.0 / indexedProps.size());
+ return plan.setCostPerEntry(1.0 / costPerEntryFactor);
}
}
//TODO Support for path restrictions
- //TODO support for NodeTypes
//TODO Support for property existence queries
//TODO support for nodeName queries
return null;
}
+ private static Set<String> getSuperTypes(Filter filter) {
+ if (filter != null && !filter.matchesAllTypes()) {
+ return filter.getSupertypes();
+ }
+ return null;
+ }
+
private IndexPlan.Builder defaultPlan() {
return new IndexPlan.Builder()
.setCostPerExecution(1) // we're local. Low-cost
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java?rev=1634792&r1=1634791&r2=1634792&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java Tue Oct 28 06:47:04 2014
@@ -36,6 +36,7 @@ import org.apache.jackrabbit.oak.api.Pro
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.IndexEditor;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateCallback;
+import org.apache.jackrabbit.oak.plugins.nodetype.TypePredicate;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -81,13 +82,21 @@ public class LuceneIndexEditor implement
private boolean propertiesChanged = false;
- LuceneIndexEditor(NodeBuilder definition, Analyzer analyzer,
- IndexUpdateCallback updateCallback) throws CommitFailedException {
+ private NodeState root;
+
+ private TypePredicate typePredicate;
+
+ LuceneIndexEditor(NodeState root, NodeBuilder definition, Analyzer analyzer,
+ IndexUpdateCallback updateCallback) throws CommitFailedException {
this.parent = null;
this.name = null;
this.path = "/";
this.context = new LuceneIndexEditorContext(definition, analyzer,
updateCallback);
+ this.root = root;
+ if (root != null && !context.getDefinition().getDeclaringNodeTypes().isEmpty()) {
+ typePredicate = new TypePredicate(root, context.getDefinition().getDeclaringNodeTypes());
+ }
}
private LuceneIndexEditor(LuceneIndexEditor parent, String name) {
@@ -95,6 +104,8 @@ public class LuceneIndexEditor implement
this.name = name;
this.path = null;
this.context = parent.context;
+ this.root = parent.root;
+ this.typePredicate = parent.typePredicate;
}
public String getPath() {
@@ -200,6 +211,11 @@ public class LuceneIndexEditor implement
//TODO Possibly we can add support for compound properties like foo/bar
//i.e. support for relative path restrictions
+ // Check for declaringNodeType validity
+ if (typePredicate != null && !typePredicate.apply(state)) {
+ return null;
+ }
+
List<Field> fields = new ArrayList<Field>();
boolean dirty = false;
for (PropertyState property : state.getProperties()) {
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java?rev=1634792&r1=1634791&r2=1634792&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java Tue Oct 28 06:47:04 2014
@@ -51,7 +51,7 @@ public class LuceneIndexEditorProvider i
String type, NodeBuilder definition, NodeState root, IndexUpdateCallback callback)
throws CommitFailedException {
if (TYPE_LUCENE.equals(type)) {
- return new LuceneIndexEditor(definition, analyzer, callback);
+ return new LuceneIndexEditor(root, definition, analyzer, callback);
}
return null;
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java?rev=1634792&r1=1634791&r2=1634792&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java Tue Oct 28 06:47:04 2014
@@ -29,6 +29,7 @@ import java.util.Set;
import javax.jcr.PropertyType;
import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.Oak;
@@ -118,6 +119,7 @@ public class LucenePropertyIndexTest ext
@Test
public void indexSelectionVsNodeType() throws Exception {
Tree luceneIndex = createIndex("test1", of("propa"));
+ // decrease cost of lucene property index
luceneIndex.setProperty(IndexConstants.ENTRY_COUNT_PROPERTY_NAME, 5L, Type.LONG);
// Decrease cost of node type index
@@ -138,13 +140,79 @@ public class LucenePropertyIndexTest ext
root.commit();
String propaQuery = "select [jcr:path] from [nt:unstructured] where [propa] = 'foo'";
- String explain = explain(propaQuery);
assertThat(explain(propaQuery), containsString("lucene:test1"));
assertQuery(propaQuery, paths);
}
@Test
+ public void declaringNodeTypeSameProp() throws Exception {
+ createIndex("test1", of("propa"));
+
+ Tree indexWithType = createIndex("test2", of("propa"));
+ indexWithType.setProperty(PropertyStates
+ .createProperty(IndexConstants.DECLARING_NODE_TYPES, of("nt:unstructured"),
+ Type.STRINGS));
+
+ Tree test = root.getTree("/").addChild("test");
+ test.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ root.commit();
+
+ Tree a = test.addChild("a");
+ a.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ a.setProperty("propa", "foo");
+ Tree b = test.addChild("b");
+ b.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ b.setProperty("propa", "foo");
+
+ test.addChild("c").setProperty("propa", "foo");
+ test.addChild("d").setProperty("propa", "foo");
+
+ root.commit();
+
+ String propabQuery = "select [jcr:path] from [nt:unstructured] where [propa] = 'foo'";
+ assertThat(explain(propabQuery), containsString("lucene:test2"));
+ assertQuery(propabQuery, asList("/test/a", "/test/b"));
+
+ String propcdQuery = "select [jcr:path] from [nt:base] where [propa] = 'foo'";
+ assertThat(explain(propcdQuery), containsString("lucene:test1"));
+ assertQuery(propcdQuery, asList("/test/a", "/test/b", "/test/c", "/test/d"));
+ }
+
+ @Test
+ public void declaringNodeTypeSingleIndex() throws Exception {
+ Tree indexWithType = createIndex("test2", of("propa", "propb"));
+ indexWithType.setProperty(PropertyStates
+ .createProperty(IndexConstants.DECLARING_NODE_TYPES, of("nt:unstructured"),
+ Type.STRINGS));
+
+ Tree test = root.getTree("/").addChild("test");
+ test.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ root.commit();
+
+ Tree a = test.addChild("a");
+ a.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ a.setProperty("propa", "foo");
+ a.setProperty("propb", "baz");
+
+ Tree b = test.addChild("b");
+ b.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+ b.setProperty("propa", "foo");
+ b.setProperty("propb", "baz");
+
+ root.commit();
+
+ String propabQuery = "select [jcr:path] from [nt:unstructured] where [propb] = 'baz' and " +
+ "[propa] = 'foo'";
+ assertThat(explain(propabQuery), containsString("lucene:test2"));
+ assertQuery(propabQuery, asList("/test/a", "/test/b"));
+
+ String propNoIdxQuery = "select [jcr:path] from [nt:base] where [propb] = 'baz'";
+ assertThat(explain(propNoIdxQuery), containsString("no-index"));
+ assertQuery(propNoIdxQuery, ImmutableList.<String>of());
+ }
+
+ @Test
public void rangeQueriesWithLong() throws Exception {
Tree idx = createIndex("test1", of("propa", "propb"));
Tree propIdx = idx.addChild(PROP_NODE).addChild("propa");