Author: tommaso
Date: Thu Nov 26 09:42:34 2015
New Revision: 1716588
URL: http://svn.apache.org/viewvc?rev=1716588&view=rev
Log:
OAK-3149 - allow analyzer to be used for fine grained suggestions
Modified:
jackrabbit/oak/trunk/oak-doc/src/site/markdown/query/lucene.md
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/LuceneIndexConstants.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorContext.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/package-info.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/CRTokenizer.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/SuggestTest.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexSuggestionTest.java
Modified: jackrabbit/oak/trunk/oak-doc/src/site/markdown/query/lucene.md
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/query/lucene.md?rev=1716588&r1=1716587&r2=1716588&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/query/lucene.md (original)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/query/lucene.md Thu Nov 26
09:42:34 2015
@@ -943,8 +943,6 @@ updated every 10 minutes but that can be
Sample configuration for suggestions based on terms contained in
`jcr:description`
property.
-Since Oak 1.3.11, the each suggestion would be returned per row.
-
```
/oak:index/lucene-suggest
- jcr:primaryType = "oak:QueryIndexDefinition"
@@ -963,6 +961,23 @@ Since Oak 1.3.11, the each suggestion wo
- useInSuggest = true
```
+`@since Oak 1.3.11` each suggestion would be returned per row.
+
+`@since Oak 1.3.12` the index Analyzer can be used to perform a have more fine
grained suggestions, e.g. single words
+(whereas default suggest configuration returns entire property values, see
[OAK-3149]: https://issues.apache.org/jira/browse/OAK-3149).
+Analyzed suggestions can be enabled by setting "suggestAnalyzed" property to
true, e.g.:
+
+```
+/oak:index/lucene-suggest
+ - jcr:primaryType = "oak:QueryIndexDefinition"
+ - compatVersion = 2
+ - type = "lucene"
+ - async = "async"
+ - suggestUpdateFrequencyMinutes = 60
+ - suggestAnalyzed = true
+```
+
+
#### Spellchecking
`@since Oak 1.1.17, 1.0.13`
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=1716588&r1=1716587&r2=1716588&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
Thu Nov 26 09:42:34 2015
@@ -218,6 +218,8 @@ class IndexDefinition implements Aggrega
private final boolean saveDirListing;
+ private final boolean suggestAnalyzed;
+
public IndexDefinition(NodeState root, NodeState defn) {
this(root, defn, null);
}
@@ -283,6 +285,7 @@ class IndexDefinition implements Aggrega
this.pathFilter = PathFilter.from(new ReadOnlyBuilder(defn));
this.queryPaths = getQueryPaths(defn);
this.saveDirListing = getOptionalValue(defn,
LuceneIndexConstants.SAVE_DIR_LISTING, true);
+ this.suggestAnalyzed = getOptionalValue(defn,
LuceneIndexConstants.SUGGEST_ANALYZED, false);
}
public boolean isFullTextEnabled() {
@@ -624,6 +627,10 @@ class IndexDefinition implements Aggrega
return definition.getString(LuceneIndexConstants.INDEX_PATH);
}
+ public boolean isSuggestAnalyzed() {
+ return suggestAnalyzed;
+ }
+
public class IndexingRule {
private final String baseNodeType;
private final String nodeTypeName;
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=1716588&r1=1716587&r2=1716588&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
Thu Nov 26 09:42:34 2015
@@ -284,4 +284,10 @@ public interface LuceneIndexConstants {
* existing index files
*/
String INDEX_PATH = "indexPath";
+
+ /**
+ * Optional property to set the suggest field to be analyzed and therefore
allow more fine
+ * grained and flexible suggestions.
+ */
+ String SUGGEST_ANALYZED = "suggestAnalyzed";
}
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorContext.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorContext.java?rev=1716588&r1=1716587&r2=1716588&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorContext.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorContext.java
Thu Nov 26 09:42:34 2015
@@ -16,12 +16,8 @@
*/
package org.apache.jackrabbit.oak.plugins.index.lucene;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.apache.jackrabbit.oak.commons.IOUtils.humanReadableByteCount;
-import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PERSISTENCE_PATH;
-import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.VERSION;
-import static org.apache.lucene.store.NoLockFactory.getNoLockFactory;
-
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -32,9 +28,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
@@ -62,6 +55,12 @@ import org.apache.tika.parser.Parser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.jackrabbit.oak.commons.IOUtils.humanReadableByteCount;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PERSISTENCE_PATH;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.VERSION;
+import static org.apache.lucene.store.NoLockFactory.getNoLockFactory;
+
public class LuceneIndexEditorContext {
private static final Logger log = LoggerFactory
@@ -79,7 +78,9 @@ public class LuceneIndexEditorContext {
Analyzer definitionAnalyzer = definition.getAnalyzer();
Map<String, Analyzer> analyzers = new HashMap<String, Analyzer>();
analyzers.put(FieldNames.SPELLCHECK, new
ShingleAnalyzerWrapper(LuceneIndexConstants.ANALYZER, 3));
- analyzers.put(FieldNames.SUGGEST, SuggestHelper.getAnalyzer());
+ if (!definition.isSuggestAnalyzed()) {
+ analyzers.put(FieldNames.SUGGEST, SuggestHelper.getAnalyzer());
+ }
Analyzer analyzer = new
PerFieldAnalyzerWrapper(definitionAnalyzer, analyzers);
IndexWriterConfig config = new IndexWriterConfig(VERSION,
analyzer);
if (remoteDir) {
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/package-info.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/package-info.java?rev=1716588&r1=1716587&r2=1716588&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/package-info.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/package-info.java
Thu Nov 26 09:42:34 2015
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("2.7.0")
+@Version("2.8.0")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.plugins.index.lucene;
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/CRTokenizer.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/CRTokenizer.java?rev=1716588&r1=1716587&r2=1716588&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/CRTokenizer.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/CRTokenizer.java
Thu Nov 26 09:42:34 2015
@@ -25,10 +25,8 @@ import org.apache.lucene.util.Version;
/**
* A {@link org.apache.lucene.analysis.util.CharTokenizer} dividing tokens at
<code>\n</code>.
- * <p/>
- * This should be deprecated/removed and not used anymore in {@link
org.apache.jackrabbit.oak.plugins.index.lucene.util.SuggestHelper}
- * (and related 'suggest fields merging code' removed in {@link
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexEditor})
- * if / once LUCENE-5833 fix gets included in the Lucene version we ship.
+ *
+ * This should be deprecated if / once LUCENE-5833 fix gets included in the
Lucene version we ship.
*/
public class CRTokenizer extends CharTokenizer {
public CRTokenizer(Version matchVersion, Reader input) {
Modified:
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/SuggestTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/SuggestTest.java?rev=1716588&r1=1716587&r2=1716588&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/SuggestTest.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/SuggestTest.java
Thu Nov 26 09:42:34 2015
@@ -26,14 +26,13 @@ import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
+import java.util.List;
import com.google.common.collect.Lists;
import org.apache.jackrabbit.core.query.AbstractQueryTest;
import org.junit.After;
import org.junit.Before;
-import java.util.List;
-
/**
* Tests the suggest support.
*/
@@ -106,6 +105,29 @@ public class SuggestTest extends Abstrac
assertTrue(result.contains("in 2015 my fox is red, like mike's fox and
john's fox"));
}
+// public void testSuggestAnalyzed() throws Exception {
+//
superuser.getNode("/oak:index/luceneGlobal").setProperty("suggestAnalyzed",
true);
+//
+// try {
+// Session session = superuser;
+// QueryManager qm = session.getWorkspace().getQueryManager();
+// Node n1 = testRootNode.addNode("node1");
+// n1.setProperty("jcr:title", "all along 2015 my fox has been red,
like mike's fox and john's fox");
+// Node n2 = testRootNode.addNode("node2");
+// n2.setProperty("jcr:title", "in 2015 a red fox is still a fox,
although not jeff's fox");
+// session.save();
+//
+// String xpath = "/jcr:root[rep:suggest('al')]/(rep:suggest())";
+// Query q = qm.createQuery(xpath, Query.XPATH);
+// List<String> result = getResult(q.execute(), "rep:suggest()");
+// assertNotNull(result);
+// assertTrue(result.contains("all"));
+// assertTrue(result.contains("although"));
+// } finally {
+//
superuser.getNode("/oak:index/luceneGlobal").setProperty("suggestAnalyzed",
false);
+// }
+// }
+
public void testNoSuggestions() throws Exception {
Session session = superuser;
QueryManager qm = session.getWorkspace().getQueryManager();
Modified:
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexSuggestionTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexSuggestionTest.java?rev=1716588&r1=1716587&r2=1716588&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexSuggestionTest.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexSuggestionTest.java
Thu Nov 26 09:42:34 2015
@@ -71,7 +71,7 @@ public class LuceneIndexSuggestionTest {
root = session.getRootNode();
}
- private void createSuggestIndex(String name, String indexedNodeType,
String indexedPropertyName, boolean addFullText)
+ private void createSuggestIndex(String name, String indexedNodeType,
String indexedPropertyName, boolean addFullText, boolean suggestAnalyzed)
throws Exception {
Node def = root.getNode(INDEX_DEFINITIONS_NAME)
.addNode(name, INDEX_DEFINITIONS_NODE_TYPE);
@@ -79,6 +79,10 @@ public class LuceneIndexSuggestionTest {
def.setProperty(REINDEX_PROPERTY_NAME, true);
def.setProperty("name", name);
def.setProperty(LuceneIndexConstants.COMPAT_MODE,
IndexFormatVersion.V2.getVersion());
+ if (suggestAnalyzed) {
+ def.setProperty("suggestAnalyzed", suggestAnalyzed);
+ }
+
Node propertyIdxDef = def.addNode(INDEX_RULES,
JcrConstants.NT_UNSTRUCTURED)
.addNode(indexedNodeType, JcrConstants.NT_UNSTRUCTURED)
@@ -100,12 +104,12 @@ public class LuceneIndexSuggestionTest {
private void checkSuggestions(final String nodeType,
final String indexPropName, final String
indexPropValue,
final boolean addFullText, final boolean
useUserSession,
- final String suggestQueryText, final boolean
shouldSuggest)
+ final String suggestQueryText, final boolean
shouldSuggest, final boolean suggestAnalyzed)
throws Exception {
checkSuggestions(nodeType, nodeType,
indexPropName, indexPropValue,
addFullText, useUserSession,
- suggestQueryText, shouldSuggest);
+ suggestQueryText, shouldSuggest, suggestAnalyzed);
}
/**
@@ -115,9 +119,10 @@ public class LuceneIndexSuggestionTest {
private void checkSuggestions(final String indexNodeType, final String
queryNodeType,
final String indexPropName, final String
indexPropValue,
final boolean addFullText, final boolean
useUserSession,
- final String suggestQueryText, final boolean
shouldSuggest)
+ final String suggestQueryText, final boolean
shouldSuggest,
+ final boolean suggestAnalyzed)
throws Exception {
- createSuggestIndex("lucene-suggest", indexNodeType, indexPropName,
addFullText);
+ createSuggestIndex("lucene-suggest", indexNodeType, indexPropName,
addFullText, suggestAnalyzed);
Node indexedNode = root.addNode("indexedNode1", queryNodeType);
indexedNode.setProperty(indexPropName, indexPropValue + " 1");
@@ -170,7 +175,7 @@ public class LuceneIndexSuggestionTest {
checkSuggestions(nodeType,
indexPropName, indexPropValue,
false, false,
- suggestQueryText, shouldSuggest);
+ suggestQueryText, shouldSuggest, false);
}
//OAK-3156
@@ -185,7 +190,7 @@ public class LuceneIndexSuggestionTest {
checkSuggestions(nodeType,
indexPropName, indexPropValue,
false, true,
- suggestQueryText, shouldSuggest);
+ suggestQueryText, shouldSuggest, false);
}
//OAK-3156
@@ -201,7 +206,7 @@ public class LuceneIndexSuggestionTest {
checkSuggestions(indexNodeType, queryNodeType,
indexPropName, indexPropValue,
true, false,
- suggestQueryText, shouldSuggest);
+ suggestQueryText, shouldSuggest, false);
}
//OAK-3156
@@ -216,7 +221,7 @@ public class LuceneIndexSuggestionTest {
checkSuggestions(nodeType,
indexPropName, indexPropValue,
true, false,
- suggestQueryText, shouldSuggest);
+ suggestQueryText, shouldSuggest, false);
}
//OAK-3509
@@ -231,6 +236,34 @@ public class LuceneIndexSuggestionTest {
checkSuggestions(nodeType,
indexPropName, indexPropValue,
true, false,
- suggestQueryText, shouldSuggest);
+ suggestQueryText, shouldSuggest, false);
+ }
+
+ //OAK-3407
+ @Test
+ public void testSuggestQueryAnalyzed() throws Exception {
+ final String nodeType = "nt:unstructured";
+ final String indexPropName = "description";
+ final String indexPropValue = "this is just a sample text which should
get some response in suggestions";
+ final String suggestQueryText = "sa";
+
+ checkSuggestions(nodeType,
+ indexPropName, indexPropValue,
+ true, true,
+ suggestQueryText, true, true);
+ }
+
+ //OAK-3149
+ @Test
+ public void testSuggestQueryInfix() throws Exception {
+ final String nodeType = "nt:unstructured";
+ final String indexPropName = "description";
+ final String indexPropValue = "this is just a sample text which should
get some response in suggestions";
+ final String suggestQueryText = "sa";
+
+ checkSuggestions(nodeType,
+ indexPropName, indexPropValue,
+ true, true,
+ suggestQueryText, true, false);
}
}