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 al...@apache.org on 2014/04/02 21:04:22 UTC
svn commit: r1584132 - 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: alexparvulescu
Date: Wed Apr 2 19:04:22 2014
New Revision: 1584132
URL: http://svn.apache.org/r1584132
Log:
OAK-1668 Lucene should not serve queries for what it doesn't index
Added:
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexExclusionQueryTest.java (with props)
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java?rev=1584132&r1=1584131&r2=1584132&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java Wed Apr 2 19:04:22 2014
@@ -28,6 +28,8 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldNames.PATH;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldNames.PATH_SELECTOR;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.EXCLUDE_PROPERTY_NAMES;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INCLUDE_PROPERTY_TYPES;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INDEX_DATA_CHILD_NAME;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PERSISTENCE_FILE;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PERSISTENCE_NAME;
@@ -56,6 +58,8 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
+import javax.jcr.PropertyType;
+
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.plugins.index.aggregate.NodeAggregator;
import org.apache.jackrabbit.oak.plugins.index.lucene.util.MoreLikeThisHelper;
@@ -67,11 +71,11 @@ import org.apache.jackrabbit.oak.query.f
import org.apache.jackrabbit.oak.query.fulltext.FullTextTerm;
import org.apache.jackrabbit.oak.query.fulltext.FullTextVisitor;
import org.apache.jackrabbit.oak.spi.query.Cursor;
-import org.apache.jackrabbit.oak.spi.query.Filter;
-import org.apache.jackrabbit.oak.spi.query.PropertyValues;
import org.apache.jackrabbit.oak.spi.query.Cursors.PathCursor;
+import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction;
import org.apache.jackrabbit.oak.spi.query.IndexRow;
+import org.apache.jackrabbit.oak.spi.query.PropertyValues;
import org.apache.jackrabbit.oak.spi.query.QueryIndex;
import org.apache.jackrabbit.oak.spi.query.QueryIndex.FulltextQueryIndex;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
@@ -329,7 +333,7 @@ public class LuceneIndex implements Full
// we only restrict non-full-text conditions if there is
// no relative property in the full-text constraint
boolean nonFullTextConstraints = parent.isEmpty();
- String plan = getQuery(filter, null, nonFullTextConstraints, analyzer) + " ft:(" + ft + ")";
+ String plan = getQuery(filter, null, nonFullTextConstraints, analyzer, getIndexDef(root)) + " ft:(" + ft + ")";
if (!parent.isEmpty()) {
plan += " parent:" + parent;
}
@@ -363,7 +367,7 @@ public class LuceneIndex implements Full
IndexSearcher searcher = new IndexSearcher(reader);
List<LuceneResultRow> rows = new ArrayList<LuceneResultRow>();
Query query = getQuery(filter, reader,
- nonFullTextConstraints, analyzer);
+ nonFullTextConstraints, analyzer, getIndexDef(root));
// TODO OAK-828
HashSet<String> seenPaths = new HashSet<String>();
@@ -428,10 +432,11 @@ public class LuceneIndex implements Full
* path, node type, and so on) should be added to the Lucene
* query
* @param analyzer the Lucene analyzer used for building the fulltext query
+ * @param indexDefinition nodestate that contains the index definition
* @return the Lucene query
*/
private static Query getQuery(Filter filter, IndexReader reader,
- boolean nonFullTextConstraints, Analyzer analyzer) {
+ boolean nonFullTextConstraints, Analyzer analyzer, NodeState indexDefinition) {
List<Query> qs = new ArrayList<Query>();
FullTextExpression ft = filter.getFullTextConstraint();
if (ft == null) {
@@ -461,9 +466,9 @@ public class LuceneIndex implements Full
throw new RuntimeException(e);
}
}
- }
- else if (nonFullTextConstraints) {
- addNonFullTextConstraints(qs, filter, reader, analyzer);
+ } else if (nonFullTextConstraints) {
+ addNonFullTextConstraints(qs, filter, reader, analyzer,
+ indexDefinition);
}
if (qs.size() == 0) {
return new MatchAllDocsQuery();
@@ -479,7 +484,7 @@ public class LuceneIndex implements Full
}
private static void addNonFullTextConstraints(List<Query> qs,
- Filter filter, IndexReader reader, Analyzer analyzer) {
+ Filter filter, IndexReader reader, Analyzer analyzer, NodeState indexDefinition) {
if (!filter.matchesAllTypes()) {
addNodeTypeConstraints(qs, filter);
}
@@ -526,11 +531,12 @@ public class LuceneIndex implements Full
continue;
}
- String name = pr.propertyName;
- if (name.contains("/")) {
- // lucene cannot handle child-level property restrictions
+ // check excluded properties and types
+ if (isExcludedProperty(pr, indexDefinition)) {
continue;
}
+
+ String name = pr.propertyName;
if ("rep:excerpt".equals(name)) {
continue;
}
@@ -617,6 +623,44 @@ public class LuceneIndex implements Full
return token;
}
+ private static boolean isExcludedProperty(PropertyRestriction pr,
+ NodeState definition) {
+ String name = pr.propertyName;
+ if (name.contains("/")) {
+ // lucene cannot handle child-level property restrictions
+ return true;
+ }
+
+ // check name
+ for (String e : definition.getStrings(EXCLUDE_PROPERTY_NAMES)) {
+ if (e.equalsIgnoreCase(name)) {
+ return true;
+ }
+ }
+
+ // check type
+ Integer type = null;
+ if (pr.first != null) {
+ type = pr.first.getType().tag();
+ } else if (pr.last != null) {
+ type = pr.last.getType().tag();
+ } else if (pr.list != null && !pr.list.isEmpty()) {
+ type = pr.list.get(0).getType().tag();
+ }
+ if (type != null) {
+ boolean isIn = false;
+ for (String e : definition.getStrings(INCLUDE_PROPERTY_TYPES)) {
+ if (PropertyType.valueFromName(e) == type) {
+ isIn = true;
+ }
+ }
+ if (!isIn) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private static void addReferenceConstraint(String uuid, List<Query> qs,
IndexReader reader) {
if (reader == null) {
Added: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexExclusionQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexExclusionQueryTest.java?rev=1584132&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexExclusionQueryTest.java (added)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexExclusionQueryTest.java Wed Apr 2 19:04:22 2014
@@ -0,0 +1,109 @@
+/*
+ * 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 static com.google.common.collect.ImmutableList.of;
+import static javax.jcr.PropertyType.TYPENAME_BINARY;
+import static javax.jcr.PropertyType.TYPENAME_STRING;
+import static org.apache.jackrabbit.JcrConstants.JCR_LASTMODIFIED;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED;
+import static org.apache.jackrabbit.oak.api.Type.DATE;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.EXCLUDE_PROPERTY_NAMES;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INCLUDE_PROPERTY_TYPES;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.TYPE_LUCENE;
+
+import java.util.List;
+
+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.plugins.nodetype.write.InitialContent;
+import org.apache.jackrabbit.oak.query.AbstractQueryTest;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.junit.Test;
+
+/**
+ * Tests the {@link LuceneIndexProvider} exclusion settings
+ */
+public class LuceneIndexExclusionQueryTest extends AbstractQueryTest {
+
+ private static final String NOT_IN = "notincluded";
+
+ @Override
+ protected void createTestIndexNode() throws Exception {
+ Tree lucene = createTestIndexNode(root.getTree("/"), TYPE_LUCENE);
+ lucene.setProperty(INCLUDE_PROPERTY_TYPES,
+ of(TYPENAME_BINARY, TYPENAME_STRING), STRINGS);
+ lucene.setProperty(EXCLUDE_PROPERTY_NAMES, of(NOT_IN), STRINGS);
+ root.commit();
+ }
+
+ @Override
+ protected ContentRepository createRepository() {
+ return new Oak().with(new InitialContent())
+ .with(new OpenSecurityProvider())
+ .with(new LowCostLuceneIndexProvider())
+ .with(new LuceneIndexEditorProvider())
+ .createContentRepository();
+ }
+
+ @Test
+ public void ignoreByType() throws Exception {
+ Tree content = root.getTree("/").addChild("content");
+ Tree one = content.addChild("one");
+ one.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED);
+ one.setProperty(JCR_LASTMODIFIED, "2013-04-01T09:58:03.231Z", DATE);
+ one.setProperty("jcr:title", "abc");
+
+ Tree two = content.addChild("two");
+ two.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED);
+ two.setProperty(JCR_LASTMODIFIED, "2014-04-01T09:58:03.231Z", DATE);
+ two.setProperty("jcr:title", "abc");
+
+ root.commit();
+
+ String query = "/jcr:root/content//*[jcr:contains(., 'abc' )"
+ + " and (@" + JCR_LASTMODIFIED
+ + " > xs:dateTime('2014-04-01T08:58:03.231Z')) ]";
+ assertQuery(query, "xpath", of("/content/two"));
+ }
+
+ @Test
+ public void ignoreByName() throws Exception {
+ final List<String> expected = of("/content/two");
+
+ Tree content = root.getTree("/").addChild("content");
+ Tree one = content.addChild("one");
+ one.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED);
+ one.setProperty("jcr:title", "abc");
+ one.setProperty(NOT_IN, "azerty");
+
+ Tree two = content.addChild("two");
+ two.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED);
+ two.setProperty("jcr:title", "abc");
+ two.setProperty(NOT_IN, "querty");
+
+ root.commit();
+
+ String query = "/jcr:root/content//*[jcr:contains(., 'abc' )"
+ + " and (@" + NOT_IN + " = 'querty') ]";
+ assertQuery(query, "xpath", expected);
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexExclusionQueryTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
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=1584132&r1=1584131&r2=1584132&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 Wed Apr 2 19:04:22 2014
@@ -16,6 +16,7 @@
*/
package org.apache.jackrabbit.oak.plugins.index.lucene;
+import static javax.jcr.PropertyType.TYPENAME_STRING;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -26,8 +27,6 @@ import static org.apache.jackrabbit.oak.
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 javax.jcr.PropertyType;
-
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
import org.apache.jackrabbit.oak.query.QueryEngineSettings;
@@ -63,7 +62,8 @@ public class LuceneIndexTest {
@Test
public void testLucene() throws Exception {
NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
- newLuceneIndexDefinition(index, "lucene", null);
+ newLuceneIndexDefinition(index, "lucene",
+ ImmutableSet.of(TYPENAME_STRING));
NodeState before = builder.getNodeState();
builder.setProperty("foo", "bar");
@@ -85,7 +85,8 @@ public class LuceneIndexTest {
@Test
public void testLucene2() throws Exception {
NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
- newLuceneIndexDefinition(index, "lucene", null);
+ newLuceneIndexDefinition(index, "lucene",
+ ImmutableSet.of(TYPENAME_STRING));
NodeState before = builder.getNodeState();
builder.setProperty("foo", "bar");
@@ -116,7 +117,7 @@ public class LuceneIndexTest {
public void testLucene3() throws Exception {
NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
newLuceneIndexDefinition(index, "lucene",
- ImmutableSet.of(PropertyType.TYPENAME_STRING));
+ ImmutableSet.of(TYPENAME_STRING));
NodeState before = builder.getNodeState();
builder.setProperty("foo", "bar");