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/12/05 15:06:00 UTC
svn commit: r1643287 - 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/
Author: chetanm
Date: Fri Dec 5 14:06:00 2014
New Revision: 1643287
URL: http://svn.apache.org/r1643287
Log:
OAK-2306 - Path restriction evaluation support within LucenIndex
Added:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/TokenizerChain.java (with props)
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldFactory.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java
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/LuceneIndexConstants.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/LucenePropertyIndex.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/TermFactory.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.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/FieldFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldFactory.java?rev=1643287&r1=1643286&r2=1643287&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldFactory.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldFactory.java Fri Dec 5 14:06:00 2014
@@ -20,9 +20,11 @@ import java.util.Arrays;
import com.google.common.primitives.Ints;
import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.util.ISO8601;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.IntField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
@@ -108,6 +110,14 @@ public final class FieldFactory {
return new TextField(FieldNames.createFulltextFieldName(name), value, NO);
}
+ public static Field newAncestorsField(String path){
+ return new TextField(FieldNames.ANCESTORS, path, NO);
+ }
+
+ public static Field newDepthField(String path){
+ return new IntField(FieldNames.PATH_DEPTH, PathUtils.getDepth(path), NO);
+ }
+
/**
* Date values are saved with sec resolution
* @param date jcr data string
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java?rev=1643287&r1=1643286&r2=1643287&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java Fri Dec 5 14:06:00 2014
@@ -38,6 +38,17 @@ public final class FieldNames {
public static final String PATH = ":path";
/**
+ * Name of the field that contains all the path hierarchy e.g. for /a/b/c
+ * it would contain /a, /a/b, /a/b/c
+ */
+ public static final String ANCESTORS = ":ancestors";
+
+ /**
+ * Name of the field which refers to the depth of path
+ */
+ public static final String PATH_DEPTH = ":depth";
+
+ /**
* Name of the field that contains the fulltext index.
*/
public static final String FULLTEXT = ":fulltext";
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=1643287&r1=1643286&r2=1643287&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 Fri Dec 5 14:06:00 2014
@@ -45,6 +45,7 @@ import org.apache.jackrabbit.oak.api.Tre
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.index.lucene.util.TokenizerChain;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
import org.apache.jackrabbit.oak.plugins.tree.ImmutableTree;
@@ -53,6 +54,8 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.util.TreeUtil;
import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
+import org.apache.lucene.analysis.path.PathHierarchyTokenizerFactory;
import org.apache.lucene.codecs.Codec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -154,6 +157,8 @@ class IndexDefinition implements Aggrega
private final boolean indexesAllTypes;
+ private final Analyzer analyzer;
+
public IndexDefinition(NodeState root, NodeState defn) {
this(root, defn, null);
}
@@ -207,6 +212,7 @@ class IndexDefinition implements Aggrega
this.costPerEntry = getOptionalValue(defn, LuceneIndexConstants.COST_PER_ENTRY, 1.0);
this.costPerExecution = getOptionalValue(defn, LuceneIndexConstants.COST_PER_EXECUTION, 1.0);
this.indexesAllTypes = areAllTypesIndexed();
+ this.analyzer = createAnalyzer();
}
public boolean isFullTextEnabled() {
@@ -284,7 +290,7 @@ class IndexDefinition implements Aggrega
}
public Analyzer getAnalyzer(){
- return LuceneIndexConstants.ANALYZER;
+ return analyzer;
}
@Override
@@ -292,6 +298,19 @@ class IndexDefinition implements Aggrega
return "IndexDefinition : " + indexName;
}
+ //~---------------------------------------------------< Analyzer >
+
+ private Analyzer createAnalyzer() {
+ if (!evaluatePathRestrictions()){
+ return LuceneIndexConstants.ANALYZER;
+ }
+ Map<String, Analyzer> analyzerMap = ImmutableMap.<String, Analyzer>builder()
+ .put(FieldNames.ANCESTORS,
+ new TokenizerChain(new PathHierarchyTokenizerFactory(Collections.<String, String>emptyMap())))
+ .build();
+ return new PerFieldAnalyzerWrapper(LuceneIndexConstants.ANALYZER, analyzerMap);
+ }
+
//~---------------------------------------------------< Aggregates >
@CheckForNull
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=1643287&r1=1643286&r2=1643287&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 Fri Dec 5 14:06:00 2014
@@ -290,6 +290,7 @@ class IndexPlanner {
}
private String getPathPrefix() {
+ // 2 = /oak:index/<index name>
String parentPath = PathUtils.getAncestorPath(indexPath, 2);
return PathUtils.denotesRoot(parentPath) ? "" : parentPath;
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java?rev=1643287&r1=1643286&r2=1643287&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java Fri Dec 5 14:06:00 2014
@@ -141,7 +141,7 @@ public interface LuceneIndexConstants {
*/
String TEST_MODE = "testMode";
- String EVALUATE_PATH_RESTRICTION = "oak.experimental.evaluatePathRestrictions";
+ String EVALUATE_PATH_RESTRICTION = "evaluatePathRestrictions";
/**
* Experimental config to restrict which property type gets indexed at
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=1643287&r1=1643286&r2=1643287&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 Fri Dec 5 14:06:00 2014
@@ -19,7 +19,9 @@ package org.apache.jackrabbit.oak.plugin
import static org.apache.jackrabbit.JcrConstants.JCR_DATA;
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newDepthField;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newFulltextField;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newAncestorsField;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newPathField;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newPropertyField;
import static org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newPathTerm;
@@ -313,6 +315,12 @@ public class LuceneIndexEditor implement
if (indexingRule.isFulltextEnabled()) {
document.add(newFulltextField(name));
}
+
+ if (getDefinition().evaluatePathRestrictions()){
+ document.add(newAncestorsField(PathUtils.getParentPath(path)));
+ document.add(newDepthField(path));
+ }
+
for (Field f : fields) {
document.add(f);
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java?rev=1643287&r1=1643286&r2=1643287&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java Fri Dec 5 14:06:00 2014
@@ -102,6 +102,7 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldNames.PATH;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.VERSION;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newAncestorTerm;
import static org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newFulltextTerm;
import static org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newPathTerm;
import static org.apache.jackrabbit.oak.query.QueryImpl.JCR_PATH;
@@ -500,26 +501,22 @@ public class LucenePropertyIndex impleme
addNodeTypeConstraints(planResult.indexingRule, qs, filter);
}
- String path = filter.getPath();
- //TODO Readjust path based on pathPrefix of the index
+ String path = getPathRestriction(plan);
switch (filter.getPathRestriction()) {
case ALL_CHILDREN:
if (defn.evaluatePathRestrictions()) {
if ("/".equals(path)) {
break;
}
- if (!path.endsWith("/")) {
- path += "/";
- }
- qs.add(new PrefixQuery(newPathTerm(path)));
+ qs.add(new TermQuery(newAncestorTerm(path)));
}
break;
case DIRECT_CHILDREN:
if (defn.evaluatePathRestrictions()) {
- if (!path.endsWith("/")) {
- path += "/";
- }
- qs.add(new PrefixQuery(newPathTerm(path)));
+ BooleanQuery bq = new BooleanQuery();
+ bq.add(new BooleanClause(new TermQuery(newAncestorTerm(path)), BooleanClause.Occur.MUST));
+ bq.add(new BooleanClause(newDepthQuery(path), BooleanClause.Occur.MUST));
+ qs.add(bq);
}
break;
case EXACT:
@@ -1047,6 +1044,21 @@ public class LucenePropertyIndex impleme
return tokens;
}
+ private static String getPathRestriction(IndexPlan plan) {
+ Filter f = plan.getFilter();
+ String pathPrefix = plan.getPathPrefix();
+ if (pathPrefix.isEmpty()) {
+ return f.getPath();
+ }
+ String relativePath = PathUtils.relativize(pathPrefix, f.getPath());
+ return "/" + relativePath;
+ }
+
+ private static Query newDepthQuery(String path) {
+ int depth = PathUtils.getDepth(path) + 1;
+ return NumericRangeQuery.newIntRange(FieldNames.PATH_DEPTH, depth, depth, true, true);
+ }
+
static class LuceneResultRow {
final String path;
final double score;
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/TermFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/TermFactory.java?rev=1643287&r1=1643286&r2=1643287&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/TermFactory.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/TermFactory.java Fri Dec 5 14:06:00 2014
@@ -39,10 +39,7 @@ public final class TermFactory {
* @return the path term.
*/
public static Term newPathTerm(String path) {
- if (!"/".equals(path) && !path.startsWith("/")) {
- path = "/" + path;
- }
- return new Term(FieldNames.PATH, path);
+ return new Term(FieldNames.PATH, preparePath(path));
}
public static Term newFulltextTerm(String ft, String field) {
@@ -52,8 +49,18 @@ public final class TermFactory {
return new Term(field, ft);
}
+ public static Term newAncestorTerm(String path){
+ return new Term(FieldNames.ANCESTORS, preparePath(path));
+ }
+
public static Term newFulltextTerm(String ft) {
return new Term(FieldNames.FULLTEXT, ft);
}
+ private static String preparePath(String path) {
+ if (!"/".equals(path) && !path.startsWith("/")) {
+ path = "/" + path;
+ }
+ return path;
+ }
}
Added: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/TokenizerChain.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/TokenizerChain.java?rev=1643287&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/TokenizerChain.java (added)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/TokenizerChain.java Fri Dec 5 14:06:00 2014
@@ -0,0 +1,92 @@
+/*
+ * 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.util;
+
+import java.io.Reader;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.CharFilterFactory;
+import org.apache.lucene.analysis.util.TokenFilterFactory;
+import org.apache.lucene.analysis.util.TokenizerFactory;
+
+/**
+ * An analyzer that uses a tokenizer and a list of token filters to
+ * create a TokenStream. Taken from org.apache.solr.analysis.TokenizerChain
+ */
+public final class TokenizerChain extends Analyzer {
+ private final CharFilterFactory[] charFilters;
+ private final TokenizerFactory tokenizer;
+ private final TokenFilterFactory[] filters;
+
+ public TokenizerChain(TokenizerFactory tokenizer) {
+ this(null, tokenizer, null);
+ }
+
+ public TokenizerChain(TokenizerFactory tokenizer, TokenFilterFactory[] filters) {
+ this(null, tokenizer, filters);
+ }
+
+ public TokenizerChain(CharFilterFactory[] charFilters, TokenizerFactory tokenizer, TokenFilterFactory[] filters) {
+ this.charFilters = charFilters;
+ this.tokenizer = tokenizer;
+ this.filters = filters == null ? new TokenFilterFactory[0] : filters;
+ }
+
+ @Override
+ public Reader initReader(String fieldName, Reader reader) {
+ if (charFilters != null && charFilters.length > 0) {
+ Reader cs = reader;
+ for (CharFilterFactory charFilter : charFilters) {
+ cs = charFilter.create(cs);
+ }
+ reader = cs;
+ }
+ return reader;
+ }
+
+ @Override
+ protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
+ Tokenizer tk = tokenizer.create(reader);
+ TokenStream ts = tk;
+ for (TokenFilterFactory filter : filters) {
+ ts = filter.create(ts);
+ }
+ return new TokenStreamComponents(tk, ts);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("TokenizerChain(");
+ for (CharFilterFactory filter : charFilters) {
+ sb.append(filter);
+ sb.append(", ");
+ }
+ sb.append(tokenizer);
+ for (TokenFilterFactory filter : filters) {
+ sb.append(", ");
+ sb.append(filter);
+ }
+ sb.append(')');
+ return sb.toString();
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/TokenizerChain.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java?rev=1643287&r1=1643286&r2=1643287&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java Fri Dec 5 14:06:00 2014
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.oak.plugins.index.lucene;
import java.io.File;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -26,6 +27,7 @@ import javax.jcr.PropertyType;
import static com.google.common.collect.ImmutableList.copyOf;
import static com.google.common.collect.Iterators.transform;
+import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
import static junit.framework.Assert.assertEquals;
@@ -214,12 +216,48 @@ public class LuceneIndexTest {
assertFalse(cursor.hasNext());
}
- private FilterImpl createFilter(String nodeTypeName) {
- NodeState system = root.getChildNode(JCR_SYSTEM);
- NodeState types = system.getChildNode(JCR_NODE_TYPES);
- NodeState type = types.getChildNode(nodeTypeName);
- SelectorImpl selector = new SelectorImpl(type, nodeTypeName);
- return new FilterImpl(selector, "SELECT * FROM [" + nodeTypeName + "]", new QueryEngineSettings());
+ @Test
+ public void testPathRestrictions() throws Exception {
+ NodeBuilder idx = newLucenePropertyIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+ "lucene", ImmutableSet.of("foo"), null);
+ idx.setProperty(LuceneIndexConstants.EVALUATE_PATH_RESTRICTION, true);
+
+ NodeState before = builder.getNodeState();
+ builder.setProperty("foo", "bar");
+ builder.child("a").setProperty("foo", "bar");
+ builder.child("a1").setProperty("foo", "bar");
+ builder.child("a").child("b").setProperty("foo", "bar");
+ builder.child("a").child("b").child("c").setProperty("foo", "bar");
+
+ NodeState after = builder.getNodeState();
+
+ NodeState indexed = HOOK.processCommit(before, after,CommitInfo.EMPTY);
+
+ IndexTracker tracker = new IndexTracker();
+ tracker.update(indexed);
+ AdvancedQueryIndex queryIndex = new LucenePropertyIndex(tracker);
+
+ FilterImpl filter = createTestFilter();
+ filter.restrictPath("/", Filter.PathRestriction.EXACT);
+ assertFilter(filter, queryIndex, indexed, ImmutableList.of("/"));
+
+ filter = createTestFilter();
+ filter.restrictPath("/", Filter.PathRestriction.DIRECT_CHILDREN);
+ assertFilter(filter, queryIndex, indexed, ImmutableList.of("/a", "/a1"));
+
+ filter = createTestFilter();
+ filter.restrictPath("/a", Filter.PathRestriction.DIRECT_CHILDREN);
+ assertFilter(filter, queryIndex, indexed, ImmutableList.of("/a/b"));
+
+ filter = createTestFilter();
+ filter.restrictPath("/a", Filter.PathRestriction.ALL_CHILDREN);
+ assertFilter(filter, queryIndex, indexed, ImmutableList.of("/a/b", "/a/b/c"));
+ }
+
+ private FilterImpl createTestFilter(){
+ FilterImpl filter = createFilter(NT_BASE);
+ filter.restrictProperty("foo", Operator.EQUAL, PropertyValues.newString("bar"));
+ return filter;
}
@Test
@@ -366,6 +404,13 @@ public class LuceneIndexTest {
}
}
+ private FilterImpl createFilter(String nodeTypeName) {
+ NodeState system = root.getChildNode(JCR_SYSTEM);
+ NodeState types = system.getChildNode(JCR_NODE_TYPES);
+ NodeState type = types.getChildNode(nodeTypeName);
+ SelectorImpl selector = new SelectorImpl(type, nodeTypeName);
+ return new FilterImpl(selector, "SELECT * FROM [" + nodeTypeName + "]", new QueryEngineSettings());
+ }
private void assertQuery(IndexTracker tracker, NodeState indexed, String key, String value){
AdvancedQueryIndex queryIndex = new LucenePropertyIndex(tracker);
@@ -380,6 +425,23 @@ public class LuceneIndexTest {
assertFalse(cursor.hasNext());
}
+ private static List<String> assertFilter(Filter filter, AdvancedQueryIndex queryIndex,
+ NodeState indexed, List<String> expected) {
+ List<IndexPlan> plans = queryIndex.getPlans(filter, null, indexed);
+ Cursor cursor = queryIndex.query(plans.get(0), indexed);
+
+ List<String> paths = newArrayList();
+ while (cursor.hasNext()) {
+ paths.add(cursor.next().getPath());
+ }
+ Collections.sort(paths);
+ for (String p : expected) {
+ assertTrue("Expected path " + p + " not found", paths.contains(p));
+ }
+ assertEquals("Result set size is different", expected.size(), paths.size());
+ return paths;
+ }
+
private String getIndexDir(){
File dir = new File("target", "indexdir"+System.nanoTime());
dirs.add(dir);
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=1643287&r1=1643286&r2=1643287&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 Fri Dec 5 14:06:00 2014
@@ -422,6 +422,7 @@ public class LucenePropertyIndexTest ext
public void indexDefinitionBelowRoot() throws Exception {
Tree parent = root.getTree("/").addChild("test");
Tree idx = createIndex(parent, "test1", of("propa", "propb"));
+ idx.setProperty(LuceneIndexConstants.EVALUATE_PATH_RESTRICTION, true);
idx.addChild(PROP_NODE).addChild("propa");
root.commit();
@@ -432,7 +433,21 @@ public class LucenePropertyIndexTest ext
assertQuery("select [jcr:path] from [nt:base] as s where ISDESCENDANTNODE(s, '/test') and propa = 'a'", asList("/test/test2/a"));
}
+ @Test
+ public void indexDefinitionBelowRoot2() throws Exception {
+ Tree parent = root.getTree("/").addChild("test");
+ Tree idx = createIndex(parent, "test1", of("propa", "propb"));
+ idx.setProperty(LuceneIndexConstants.EVALUATE_PATH_RESTRICTION, true);
+ idx.addChild(PROP_NODE).addChild("propa");
+ root.commit();
+ Tree test = parent.addChild("test2").addChild("test3");
+ test.addChild("a").setProperty("propa", "a");
+ root.commit();
+
+ assertQuery("select [jcr:path] from [nt:base] as s where ISDESCENDANTNODE(s, '/test/test2') and propa = 'a'",
+ asList("/test/test2/test3/a"));
+ }
@Test
public void sortQueriesWithLong() throws Exception {
Tree idx = createIndex("test1", of("foo", "bar"));