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 fo...@apache.org on 2023/03/21 10:55:00 UTC
[jackrabbit-oak] branch trunk updated: OAK-10146: oak-search-elastic: similarity search does not work for some nodes (#873)
This is an automated email from the ASF dual-hosted git repository.
fortino pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
The following commit(s) were added to refs/heads/trunk by this push:
new 05a85635b4 OAK-10146: oak-search-elastic: similarity search does not work for some nodes (#873)
05a85635b4 is described below
commit 05a85635b4d9b45a9e715951121f304d464bd5d4
Author: Fabrizio Fortino <fa...@gmail.com>
AuthorDate: Tue Mar 21 11:54:54 2023 +0100
OAK-10146: oak-search-elastic: similarity search does not work for some nodes (#873)
* OAK-10146: removed duplicate tests already part of oak-search common tests
* OAK-10146: workaround for https://github.com/elastic/elasticsearch/pull/94518
* OAK-10146: consolidate usage of java 9/10 immutable data structures
---
.../index/elastic/query/ElasticRequestHandler.java | 12 +-
.../index/elastic/ElasticSimilarQueryTest.java | 113 +++++--------------
.../plugins/index/elastic/ElasticTestServer.java | 19 ++--
.../oak/plugins/index/IndexQueryCommonTest.java | 123 +++++++++++----------
4 files changed, 106 insertions(+), 161 deletions(-)
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/query/ElasticRequestHandler.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/query/ElasticRequestHandler.java
index 5a61bee0e1..324945d801 100644
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/query/ElasticRequestHandler.java
+++ b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/query/ElasticRequestHandler.java
@@ -35,7 +35,6 @@ import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
@@ -116,7 +115,7 @@ public class ElasticRequestHandler {
private static final Logger LOG = LoggerFactory.getLogger(ElasticRequestHandler.class);
private final static String SPELLCHECK_PREFIX = "spellcheck?term=";
protected final static String SUGGEST_PREFIX = "suggest?term=";
- private static final List<SortOptions> DEFAULT_SORTS = Arrays.asList(
+ private static final List<SortOptions> DEFAULT_SORTS = List.of(
SortOptions.of(so -> so.field(f -> f.field("_score").order(SortOrder.Desc))),
SortOptions.of(so -> so.field(f -> f.field(FieldNames.PATH).order(SortOrder.Asc)))
);
@@ -389,11 +388,14 @@ public class ElasticRequestHandler {
// We store path as the _id so no need to do anything extra here
// We expect Similar impl to send a query where text would have evaluated to
// node path.
- mlt.like(l -> l.document(d -> d.id(id)));
+ mlt.like(l -> l.document(d -> d.id(id)
+ // this is needed to workaround https://github.com/elastic/elasticsearch/pull/94518 that causes empty
+ // results when the _ignored metadata field is part of the input document
+ .perFieldAnalyzer("_ignored", "keyword")));
} else {
// This is for native queries if someone sends additional fields via
// mlt.fl=field1,field2
- mlt.like(l -> l.document(d -> d.fields(Arrays.asList(fields.split(","))).id(id)));
+ mlt.like(l -> l.document(d -> d.fields(List.of(fields.split(","))).id(id)));
}
// include the input doc to align the Lucene behaviour TODO: add configuration
// parameter
@@ -424,7 +426,7 @@ public class ElasticRequestHandler {
mltParamSetter.accept(MoreLikeThisHelperUtil.MLT_STOP_WORDS, (val) -> {
// TODO : Read this from a stopwords text file, configured via index defn maybe
// ?
- mlt.stopWords(Arrays.asList(val.split(",")));
+ mlt.stopWords(List.of(val.split(",")));
});
if (!shallowMltParams.isEmpty()) {
diff --git a/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticSimilarQueryTest.java b/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticSimilarQueryTest.java
index 74696a4b47..b4a51d6c51 100644
--- a/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticSimilarQueryTest.java
+++ b/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticSimilarQueryTest.java
@@ -32,13 +32,10 @@ import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
@@ -48,6 +45,7 @@ import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import static org.apache.jackrabbit.oak.plugins.index.elastic.util.ElasticIndexUtils.toByteArray;
import static org.apache.jackrabbit.oak.plugins.index.elastic.util.ElasticIndexUtils.toDoubles;
@@ -56,79 +54,6 @@ import static org.junit.Assert.assertNotEquals;
public class ElasticSimilarQueryTest extends ElasticAbstractQueryTest {
- /*
- This test mirror the test org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexQueryTest#testRepSimilarAsNativeQuery
- Exact same test data, to test out for feature parity
- The only difference is the same query in lucene returns the doc itself (the one that we need similar docs of) as part of search results
- whereas in elastic, it doesn't.
- */
- @Test
- public void repSimilarAsNativeQuery() throws Exception {
-
- createIndex(true);
-
- String nativeQueryString = "select [jcr:path] from [nt:base] where " +
- "native('elastic-sim', 'mlt?stream.body=/test/c&mlt.fl=:path&mlt.mindf=0&mlt.mintf=0')";
- Tree test = root.getTree("/").addChild("test");
- test.addChild("a").setProperty("text", "Hello World");
- test.addChild("b").setProperty("text", "He said Hello and then the world said Hello as well.");
- test.addChild("c").setProperty("text", "He said Hi.");
- root.commit();
-
- assertEventually(() -> assertQuery(nativeQueryString, Arrays.asList("/test/c", "/test/b")));
- }
-
- /*
- This test mirror the test org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexQueryTest#testRepSimilarQuery
- Exact same test data, to test out for feature parity
- The only difference is the same query in lucene returns the doc itself (the one that we need similar docs of) as part of search results
- whereas in elastic, it doesn't.
- */
- @Test
- public void repSimilarQuery() throws Exception {
- createIndex(false);
-
- String query = "select [jcr:path] from [nt:base] where similar(., '/test/a')";
- Tree test = root.getTree("/").addChild("test");
- test.addChild("a").setProperty("text", "Hello World Hello World");
- test.addChild("b").setProperty("text", "Hello World");
- test.addChild("c").setProperty("text", "World");
- test.addChild("d").setProperty("text", "Hello");
- test.addChild("e").setProperty("text", "Bye Bye");
- test.addChild("f").setProperty("text", "Hello");
- test.addChild("g").setProperty("text", "World");
- test.addChild("h").setProperty("text", "Hello");
- root.commit();
-
- assertEventually(() -> assertQuery(query,
- Arrays.asList("/test/a", "/test/b", "/test/c", "/test/d", "/test/f", "/test/g", "/test/h")));
- }
-
- /*
- This test mirror the test org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexQueryTest#testRepSimilarXPathQuery
- Exact same test data, to test out for feature parity
- The only difference is the same query in lucene returns the doc itself (the one that we need similar docs of) as part of search results
- whereas in elastic, it doesn't.
- */
- @Test
- public void repSimilarXPathQuery() throws Exception {
- createIndex(false);
-
- String query = "//element(*, nt:base)[rep:similar(., '/test/a')]";
- Tree test = root.getTree("/").addChild("test");
- test.addChild("a").setProperty("text", "Hello World Hello World");
- test.addChild("b").setProperty("text", "Hello World");
- test.addChild("c").setProperty("text", "World");
- test.addChild("d").setProperty("text", "Hello");
- test.addChild("e").setProperty("text", "Bye Bye");
- test.addChild("f").setProperty("text", "Hello");
- test.addChild("g").setProperty("text", "World");
- test.addChild("h").setProperty("text", "Hello");
- root.commit();
- assertEventually(() -> assertQuery(query, XPATH,
- Arrays.asList("/test/a", "/test/b", "/test/c", "/test/d", "/test/f", "/test/g", "/test/h")));
- }
-
@Test
public void repSimilarWithStopWords() throws Exception {
createIndex(true);
@@ -150,11 +75,10 @@ public class ElasticSimilarQueryTest extends ElasticAbstractQueryTest {
root.commit();
// Matches due to terms Hello or bye should be ignored
- assertEventually(() -> assertQuery(nativeQueryStringWithStopWords,
- Arrays.asList("/test/a", "/test/e", "/test/f")));
+ assertEventually(() -> assertQuery(nativeQueryStringWithStopWords, List.of("/test/a", "/test/e", "/test/f")));
assertEventually(() -> assertQuery(nativeQueryStringWithoutStopWords,
- Arrays.asList("/test/a", "/test/b", "/test/c", "/test/d", "/test/e", "/test/f")));
+ List.of("/test/a", "/test/b", "/test/c", "/test/d", "/test/e", "/test/f")));
}
@Test
@@ -175,11 +99,10 @@ public class ElasticSimilarQueryTest extends ElasticAbstractQueryTest {
// Matches because of term Hello should be ignored since wl <6 (so /test/ should NOT be in the match list)
// /test/d should be in match list (because of Worlds term)
- assertEventually(() -> assertQuery(nativeQueryStringWithMinWordLength,
- Arrays.asList("/test/a", "/test/c", "/test/d")));
+ assertEventually(() -> assertQuery(nativeQueryStringWithMinWordLength, List.of("/test/a", "/test/c", "/test/d")));
assertEventually(() -> assertQuery(nativeQueryStringWithoutMinWordLength,
- Arrays.asList("/test/a", "/test/b", "/test/c", "/test/d")));
+ List.of("/test/a", "/test/b", "/test/c", "/test/d")));
}
@Test
@@ -204,7 +127,25 @@ public class ElasticSimilarQueryTest extends ElasticAbstractQueryTest {
String query = "select [jcr:path] from [nt:base] where similar(., '" + p + "')";
assertEventually(() -> assertQuery(query,
- Arrays.asList(p, "/test/b", "/test/c", "/test/d", "/test/f", "/test/g", "/test/h")));
+ List.of(p, "/test/b", "/test/c", "/test/d", "/test/f", "/test/g", "/test/h")));
+ }
+
+ /**
+ * Validates the workaround for <a href="https://github.com/elastic/elasticsearch/pull/94518">94518</a> produces the
+ * expected results
+ */
+ @Test
+ public void repSimilarQueryWithIgnoredMetadataField() throws Exception {
+ createIndex(false);
+ Tree test = root.getTree("/").addChild("test");
+
+ // the max keyword length is 256, this field will be then listed as _ignored
+ test.addChild("a").setProperty("text", ElasticTestUtils.randomString(1000));
+ root.commit();
+
+ String query = "select [jcr:path] from [nt:base] where similar(., '/test/a')";
+
+ assertEventually(() -> assertQuery(query, List.of("/test/a")));
}
@Test
@@ -278,7 +219,7 @@ public class ElasticSimilarQueryTest extends ElasticAbstractQueryTest {
for (String line : IOUtils.readLines(Files.newInputStream(file.toPath()), Charset.defaultCharset())) {
String[] split = line.split(",");
- List<Double> values = Arrays.stream(split).skip(1).map(Double::parseDouble).collect(Collectors.toList());
+ List<Double> values = Stream.of(split).skip(1).map(Double::parseDouble).collect(Collectors.toList());
byte[] bytes = toByteArray(values);
List<Double> actual = toDoubles(bytes);
assertEquals(values, actual);
@@ -305,10 +246,10 @@ public class ElasticSimilarQueryTest extends ElasticAbstractQueryTest {
URI uri = getClass().getResource("/org/apache/jackrabbit/oak/query/fvs.csv").toURI();
File file = new File(uri);
- Collection<String> children = new LinkedList<>();
+ List<String> children = new LinkedList<>();
for (String line : IOUtils.readLines(Files.newInputStream(file.toPath()), Charset.defaultCharset())) {
String[] split = line.split(",");
- List<Double> values = Arrays.stream(split).skip(1).map(Double::parseDouble).collect(Collectors.toList());
+ List<Double> values = Stream.of(split).skip(1).map(Double::parseDouble).collect(Collectors.toList());
byte[] bytes = toByteArray(values);
List<Double> actual = toDoubles(bytes);
assertEquals(values, actual);
diff --git a/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticTestServer.java b/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticTestServer.java
index dcfc39abae..baf65a33bd 100644
--- a/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticTestServer.java
+++ b/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticTestServer.java
@@ -18,7 +18,6 @@ package org.apache.jackrabbit.oak.plugins.index.elastic;
import co.elastic.clients.transport.Version;
import com.github.dockerjava.api.DockerClient;
-import com.google.common.collect.ImmutableMap;
import org.apache.jackrabbit.oak.commons.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,15 +41,15 @@ import static org.junit.Assume.assumeNotNull;
public class ElasticTestServer implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(ElasticTestServer.class);
- private static final Map<String, String> PLUGIN_OFFICIAL_RELEASES_DIGEST_MAP = ImmutableMap.<String, String>builder()
- .put("7.17.3.0", "5e3b40bb72b2813f927be9bf6ecdf88668d89d2ef20c7ebafaa51ab8407fd179")
- .put("7.17.6.0", "326893bb98ef1a0c569d9f4c4a9a073e53361924f990b17e87077985ce8a7478")
- .put("7.17.7.0", "4252eb55cc7775f1b889d624ac335abfa2e357931c40d0accb4d520144246b8b")
- .put("8.3.3.0", "14d3223456f4b9f00f86628ec8400cb46513935e618ae0f5d0d1088739ccc233")
- .put("8.4.1.0", "56797a1bac6ceeaa36d2358f818b14633124d79c5e04630fa3544603d82eaa01")
- .put("8.4.2.0", "5ce81ad043816900a496ad5b3cce7de1d99547ebf92aa1f9856343e48580c71c")
- .put("8.4.3.0", "5c00d43cdd56c5c5d8e9032ad507acea482fb5ca9445861c5cc12ad63af66425")
- .build();
+ private static final Map<String, String> PLUGIN_OFFICIAL_RELEASES_DIGEST_MAP = Map.of(
+ "7.17.3.0", "5e3b40bb72b2813f927be9bf6ecdf88668d89d2ef20c7ebafaa51ab8407fd179",
+ "7.17.6.0", "326893bb98ef1a0c569d9f4c4a9a073e53361924f990b17e87077985ce8a7478",
+ "7.17.7.0", "4252eb55cc7775f1b889d624ac335abfa2e357931c40d0accb4d520144246b8b",
+ "8.3.3.0", "14d3223456f4b9f00f86628ec8400cb46513935e618ae0f5d0d1088739ccc233",
+ "8.4.1.0", "56797a1bac6ceeaa36d2358f818b14633124d79c5e04630fa3544603d82eaa01",
+ "8.4.2.0", "5ce81ad043816900a496ad5b3cce7de1d99547ebf92aa1f9856343e48580c71c",
+ "8.4.3.0", "5c00d43cdd56c5c5d8e9032ad507acea482fb5ca9445861c5cc12ad63af66425",
+ "8.5.3.0", "d4c13f68650f9df5ff8c74ec83abc2e416de9c45f991d459326e0e2baf7b0e3f");
private static final ElasticTestServer SERVER = new ElasticTestServer();
private static volatile ElasticsearchContainer CONTAINER;
diff --git a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexQueryCommonTest.java b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexQueryCommonTest.java
index 413e51db91..ec9009fa46 100644
--- a/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexQueryCommonTest.java
+++ b/oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexQueryCommonTest.java
@@ -26,19 +26,18 @@ import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
import org.apache.jackrabbit.oak.query.AbstractQueryTest;
import org.apache.jackrabbit.oak.query.SQL2Parser;
import org.junit.After;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.event.Level;
import java.text.ParseException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
import javax.jcr.query.Query;
-import static java.util.Collections.singletonList;
-import static java.util.Arrays.asList;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED;
import static org.apache.jackrabbit.oak.api.QueryEngine.NO_BINDINGS;
@@ -48,6 +47,7 @@ import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PRO
import static org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants.PROP_VALUE_REGEX;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -222,7 +222,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
@Test
public void descendantTest2() throws Exception {
Tree test = root.getTree("/").addChild("test");
- test.addChild("a").setProperty("name", asList("Hello", "World"), STRINGS);
+ test.addChild("a").setProperty("name", List.of("Hello", "World"), STRINGS);
test.addChild("b").setProperty("name", "Hello");
root.commit();
@@ -269,18 +269,18 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
String w = "World" + System.currentTimeMillis();
Tree test = root.getTree("/").addChild("test");
- test.addChild("a").setProperty("name", asList(h, w), STRINGS);
+ test.addChild("a").setProperty("name", List.of(h, w), STRINGS);
test.addChild("b").setProperty("name", h);
root.commit();
// query 'hello'
assertEventually(() ->
- assertQuery("/jcr:root//*[jcr:contains(., '" + h + "')]", "xpath", asList("/test/a", "/test/b"))
+ assertQuery("/jcr:root//*[jcr:contains(., '" + h + "')]", "xpath", List.of("/test/a", "/test/b"))
);
// query 'world'
assertEventually(() ->
- assertQuery("/jcr:root//*[jcr:contains(., '" + w + "')]", "xpath", singletonList("/test/a"))
+ assertQuery("/jcr:root//*[jcr:contains(., '" + w + "')]", "xpath", List.of("/test/a"))
);
}
@@ -293,8 +293,8 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
test.addChild("c").setProperty("name", "hello");
root.commit();
- assertQuery("/jcr:root//*[jcr:contains(., 'hello-wor*')]", "xpath", asList("/test/a", "/test/b"));
- assertQuery("/jcr:root//*[jcr:contains(., '*hello-wor*')]", "xpath", asList("/test/a", "/test/b"));
+ assertQuery("/jcr:root//*[jcr:contains(., 'hello-wor*')]", "xpath", List.of("/test/a", "/test/b"));
+ assertQuery("/jcr:root//*[jcr:contains(., '*hello-wor*')]", "xpath", List.of("/test/a", "/test/b"));
}
@Ignore("OAK-2424")
@@ -305,8 +305,8 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
test.addChild("b").setProperty("dc:format", "progress");
root.commit();
- assertQuery("/jcr:root//*[jcr:contains(@dc:format, 'pro*')]", "xpath", singletonList("/test/b"));
- assertQuery("/jcr:root//*[jcr:contains(@dc:format, 'type:appli*')]", "xpath", singletonList("/test/a"));
+ assertQuery("/jcr:root//*[jcr:contains(@dc:format, 'pro*')]", "xpath", List.of("/test/b"));
+ assertQuery("/jcr:root//*[jcr:contains(@dc:format, 'type:appli*')]", "xpath", List.of("/test/a"));
}
@Test
@@ -316,7 +316,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
root.commit();
String stmt = "//*[jcr:contains(., '/parent/child')]";
- assertEventually(() -> assertQuery(stmt, "xpath", singletonList("/test/a")));
+ assertEventually(() -> assertQuery(stmt, "xpath", List.of("/test/a")));
}
@Test
@@ -327,7 +327,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
root.commit();
String stmt = "//*[jcr:contains(., '/segment1/segment2')]";
- assertEventually(() -> assertQuery(stmt, "xpath", singletonList("/test/a")));
+ assertEventually(() -> assertQuery(stmt, "xpath", List.of("/test/a")));
}
@Test
@@ -337,7 +337,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
root.commit();
String stmt = "//*[jcr:contains(., 'match')]";
- assertEventually(() -> assertQuery(stmt, "xpath", singletonList("/match_on_path")));
+ assertEventually(() -> assertQuery(stmt, "xpath", List.of("/match_on_path")));
}
@Test
@@ -347,7 +347,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
root.commit();
String stmt = "//*[jcr:contains(., 'match')]";
- assertEventually(() -> assertQuery(stmt, "xpath", singletonList("/match_on_path1234")));
+ assertEventually(() -> assertQuery(stmt, "xpath", List.of("/match_on_path1234")));
}
/**
@@ -371,7 +371,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
root.commit();
String stmt = "//*[jcr:contains(., 'media') and (@p = 'dam/smartcollection' or @p = 'dam/collection') ]";
- assertEventually(() -> assertQuery(stmt, "xpath", asList(one.getPath(), two.getPath())));
+ assertEventually(() -> assertQuery(stmt, "xpath", List.of(one.getPath(), two.getPath())));
}
@Test
@@ -388,13 +388,13 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
assertEquals("/test/a", result.next());
assertFalse(result.hasNext());
});
- Assert.assertNotEquals(0, logCustomizer.getLogs().size());
- Assert.assertTrue("native query WARN message is not present, message in Logger is "
+ assertNotEquals(0, logCustomizer.getLogs().size());
+ assertTrue("native query WARN message is not present, message in Logger is "
+ logCustomizer.getLogs(), logCustomizer.getLogs().get(0).contains(nativeQueryString));
}
@Test
- public void testRepSimilarAsNativeQuery() throws Exception {
+ public void repSimilarAsNativeQuery() throws Exception {
String nativeQueryString = "select [jcr:path] from [nt:base] where " +
"native('lucene', 'mlt?stream.body=/test/a&mlt.fl=:path&mlt.mindf=0&mlt.mintf=0')";
Tree test = root.getTree("/").addChild("test");
@@ -410,20 +410,20 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
assertEquals("/test/b", result.next());
assertFalse(result.hasNext());
});
- Assert.assertNotEquals(0, logCustomizer.getLogs().size());
- Assert.assertTrue("native query WARN message is not present, message in Logger is "
+ assertNotEquals(0, logCustomizer.getLogs().size());
+ assertTrue("native query WARN message is not present, message in Logger is "
+ logCustomizer.getLogs(), logCustomizer.getLogs().get(0).contains(nativeWarnLog));
}
@Test
- public void testRepSimilarQuery() throws Exception {
+ public void repSimilarQuery() throws Exception {
String query = "select [jcr:path] from [nt:base] where similar(., '/test/a')";
Tree test = root.getTree("/").addChild("test");
test.addChild("a").setProperty("text", "Hello World Hello World");
test.addChild("b").setProperty("text", "Hello World");
test.addChild("c").setProperty("text", "World");
test.addChild("d").setProperty("text", "Hello");
- test.addChild("e").setProperty("text", "World");
+ test.addChild("e").setProperty("text", "Bye Bye");
test.addChild("f").setProperty("text", "Hello");
test.addChild("g").setProperty("text", "World");
test.addChild("h").setProperty("text", "Hello");
@@ -435,18 +435,19 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
assertTrue(result.hasNext());
assertEquals("/test/b", result.next());
assertTrue(result.hasNext());
+ assertQuery(query, List.of("/test/a", "/test/b", "/test/c", "/test/d", "/test/f", "/test/g", "/test/h"));
});
}
@Test
- public void testRepSimilarXPathQuery() throws Exception {
+ public void repSimilarXPathQuery() throws Exception {
String query = "//element(*, nt:base)[rep:similar(., '/test/a')]";
Tree test = root.getTree("/").addChild("test");
test.addChild("a").setProperty("text", "Hello World Hello World");
test.addChild("b").setProperty("text", "Hello World");
test.addChild("c").setProperty("text", "World");
test.addChild("d").setProperty("text", "Hello");
- test.addChild("e").setProperty("text", "World");
+ test.addChild("e").setProperty("text", "Bye Bye");
test.addChild("f").setProperty("text", "Hello");
test.addChild("g").setProperty("text", "World");
test.addChild("h").setProperty("text", "Hello");
@@ -457,6 +458,8 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
assertEquals("/test/a", result.next());
assertTrue(result.hasNext());
assertEquals("/test/b", result.next());
+ assertQuery(query, "xpath",
+ List.of("/test/a", "/test/b", "/test/c", "/test/d", "/test/f", "/test/g", "/test/h"));
});
}
@@ -466,7 +469,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
Tree one = t.addChild("one");
one.setProperty("t", "美女衬衫");
root.commit();
- assertEventually(() -> assertQuery("//*[jcr:contains(., '美女')]", "xpath", singletonList(one.getPath())));
+ assertEventually(() -> assertQuery("//*[jcr:contains(., '美女')]", "xpath", List.of(one.getPath())));
}
@Test
@@ -474,15 +477,15 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
Tree test = root.getTree("/").addChild("test");
String child = "child";
String mulValuedProp = "prop";
- test.addChild(child).setProperty(mulValuedProp, asList("foo", "bar"), STRINGS);
+ test.addChild(child).setProperty(mulValuedProp, List.of("foo", "bar"), STRINGS);
root.commit();
- assertEventually(() -> assertQuery("/jcr:root//*[jcr:contains(@" + mulValuedProp + ", 'foo')]", "xpath", singletonList("/test/" + child)));
+ assertEventually(() -> assertQuery("/jcr:root//*[jcr:contains(@" + mulValuedProp + ", 'foo')]", "xpath", List.of("/test/" + child)));
- test.getChild(child).setProperty(mulValuedProp, new ArrayList<>(), STRINGS);
+ test.getChild(child).setProperty(mulValuedProp, List.of(), STRINGS);
root.commit();
assertEventually(() -> assertQuery("/jcr:root//*[jcr:contains(@" + mulValuedProp + ", 'foo')]", "xpath", new ArrayList<>()));
- test.getChild(child).setProperty(mulValuedProp, singletonList("bar"), STRINGS);
+ test.getChild(child).setProperty(mulValuedProp, List.of("bar"), STRINGS);
root.commit();
assertEventually(() -> assertQuery("/jcr:root//*[jcr:contains(@" + mulValuedProp + ", 'foo')]", "xpath", new ArrayList<>()));
@@ -522,19 +525,19 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
assertEventually(() -> {
assertQuery(
"SELECT * FROM [nt:unstructured] WHERE ISDESCENDANTNODE('/test') AND CONTAINS(foo, 'bar')",
- asList("/test/a", "/test/d"));
+ List.of("/test/a", "/test/d"));
assertQuery(
"SELECT * FROM [nt:unstructured] WHERE ISDESCENDANTNODE('/test') AND NOT CONTAINS(foo, 'bar')",
- asList("/test/b", "/test/c"));
+ List.of("/test/b", "/test/c"));
assertQuery(
"SELECT * FROM [nt:unstructured] WHERE ISDESCENDANTNODE('/test') AND CONTAINS(foo, 'bar cat')",
- singletonList("/test/d"));
+ List.of("/test/d"));
assertQuery(
"SELECT * FROM [nt:unstructured] WHERE ISDESCENDANTNODE('/test') AND NOT CONTAINS(foo, 'bar cat')",
- singletonList("/test/c"));
+ List.of("/test/c"));
});
setTraversalEnabled(true);
}
@@ -554,7 +557,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
root.commit();
String query = "//*[jcr:contains(@propa, 'Hello *ship')] ";
- assertEventually(() -> assertQuery(query, XPATH, Arrays.asList("/test/e")));
+ assertEventually(() -> assertQuery(query, XPATH, List.of("/test/e")));
}
@@ -572,7 +575,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
root.commit();
String query = "//*[jcr:contains(@propa, '*ship to can*')] ";
- assertEventually(() -> assertQuery(query, XPATH, Arrays.asList("/test/a", "/test/b", "/test/c")));
+ assertEventually(() -> assertQuery(query, XPATH, List.of("/test/a", "/test/b", "/test/c")));
}
@Test
@@ -594,24 +597,24 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
assertEventually(() -> {
// case insensitive
- assertQuery("//*[jcr:contains(., 'WORLD')] ", XPATH, Arrays.asList("/test/nodeb", "/test/nodec"));
+ assertQuery("//*[jcr:contains(., 'WORLD')] ", XPATH, List.of("/test/nodeb", "/test/nodec"));
// wild card
- assertQuery("//*[jcr:contains(., 'Hell*')] ", XPATH, Arrays.asList("/test/nodea", "/test/nodeb", "/test/nodec"));
- assertQuery("//*[jcr:contains(., 'He*o')] ", XPATH, Arrays.asList("/test/nodea", "/test/nodeb", "/test/nodec"));
- assertQuery("//*[jcr:contains(., '*llo')] ", XPATH, Arrays.asList("/test/nodea", "/test/nodeb", "/test/nodec"));
- assertQuery("//*[jcr:contains(., '?orld')] ", XPATH, Arrays.asList("/test/nodeb", "/test/nodec"));
- assertQuery("//*[jcr:contains(., 'wo?ld')] ", XPATH, Arrays.asList("/test/nodeb", "/test/nodec"));
- assertQuery("//*[jcr:contains(., 'worl?')] ", XPATH, Arrays.asList("/test/nodeb", "/test/nodec"));
+ assertQuery("//*[jcr:contains(., 'Hell*')] ", XPATH, List.of("/test/nodea", "/test/nodeb", "/test/nodec"));
+ assertQuery("//*[jcr:contains(., 'He*o')] ", XPATH, List.of("/test/nodea", "/test/nodeb", "/test/nodec"));
+ assertQuery("//*[jcr:contains(., '*llo')] ", XPATH, List.of("/test/nodea", "/test/nodeb", "/test/nodec"));
+ assertQuery("//*[jcr:contains(., '?orld')] ", XPATH, List.of("/test/nodeb", "/test/nodec"));
+ assertQuery("//*[jcr:contains(., 'wo?ld')] ", XPATH, List.of("/test/nodeb", "/test/nodec"));
+ assertQuery("//*[jcr:contains(., 'worl?')] ", XPATH, List.of("/test/nodeb", "/test/nodec"));
// space explained as AND
- assertQuery("//*[jcr:contains(., 'hello world')] ", XPATH, Arrays.asList("/test/nodeb", "/test/nodec"));
+ assertQuery("//*[jcr:contains(., 'hello world')] ", XPATH, List.of("/test/nodeb", "/test/nodec"));
// exclude
- assertQuery("//*[jcr:contains(., 'hello -world')] ", XPATH, Arrays.asList("/test/nodea"));
+ assertQuery("//*[jcr:contains(., 'hello -world')] ", XPATH, List.of("/test/nodea"));
// explicit OR
- assertQuery("//*[jcr:contains(., 'ocean OR world')] ", XPATH, Arrays.asList("/test/nodea", "/test/nodeb", "/test/nodec"));
+ assertQuery("//*[jcr:contains(., 'ocean OR world')] ", XPATH, List.of("/test/nodea", "/test/nodeb", "/test/nodec"));
});
}
@@ -633,7 +636,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
String query2 = "/jcr:root/test//*[propa!='bar']";
- assertEventually(() -> assertQuery(query2, XPATH, Arrays.asList("/test/test1", "/test/test2", "/test/test3")));
+ assertEventually(() -> assertQuery(query2, XPATH, List.of("/test/test1", "/test/test2", "/test/test3")));
}
@Test
@@ -652,7 +655,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
String query2 = "select * from [nt:base] as s where propa is not null and ISDESCENDANTNODE(s, '/test')";
- assertEventually(() -> assertQuery(query2, SQL2, Arrays.asList("/test/test1", "/test/test2", "/test/test3")));
+ assertEventually(() -> assertQuery(query2, SQL2, List.of("/test/test1", "/test/test2", "/test/test3")));
}
@Test
@@ -672,7 +675,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
String query2 = "//*[propa!='bar']";
- assertEventually(() -> assertQuery(query2, XPATH, Arrays.asList("/test1", "/test2", "/test3")));
+ assertEventually(() -> assertQuery(query2, XPATH, List.of("/test1", "/test2", "/test3")));
}
@Test
@@ -693,7 +696,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
String query2 = "/jcr:root/test//*[propa!='bar' and propb='world']";
// Expected - nodes with both properties defined and propb with value 'world' and propa with value not equal to bar should be returned
// /test/test6 should NOT be returned because for it propa = null
- assertEventually(() -> assertQuery(query2, XPATH, Arrays.asList("/test/test1")));
+ assertEventually(() -> assertQuery(query2, XPATH, List.of("/test/test1")));
}
@@ -713,7 +716,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
String query2 = "/jcr:root/test//*[propa='bar']";
- assertEventually(() -> assertQuery(query2, XPATH, Arrays.asList("/test/test4")));
+ assertEventually(() -> assertQuery(query2, XPATH, List.of("/test/test4")));
}
@Test
@@ -730,12 +733,12 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
// It should return both /test/test1 -> where content for propDate is of incorrect data type
// and /test/test2 -> where content for propDate is of correct data type.
String query = "/jcr:root/test//*[propa='bar']";
- assertEventually(() -> assertQuery(query, XPATH, Arrays.asList("/test/test2", "/test/test1")));
+ assertEventually(() -> assertQuery(query, XPATH, List.of("/test/test2", "/test/test1")));
// Check inequality query on propDate - this should not return /test/test1 -> since that node should not have been indexed for propDate
// due to incorrect data type in the content for this property.
String query2 = "/jcr:root/test//*[propDate!='2021-01-22T01:02:03.000Z']";
- assertEventually(() -> assertQuery(query2, XPATH, Arrays.asList("/test/test3")));
+ assertEventually(() -> assertQuery(query2, XPATH, List.of("/test/test3")));
}
@Test
@@ -750,13 +753,13 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
// Below queries will ensure propa is searchable with different data types as content and behaviour is similar for lucene and elastic.
String query = "/jcr:root/test//*[propa='bar']";
- assertEventually(() -> assertQuery(query, XPATH, Arrays.asList("/test/test1")));
+ assertEventually(() -> assertQuery(query, XPATH, List.of("/test/test1")));
String query2 = "/jcr:root/test//*[propa=true]";
- assertEventually(() -> assertQuery(query2, XPATH, Arrays.asList("/test/test4")));
+ assertEventually(() -> assertQuery(query2, XPATH, List.of("/test/test4")));
String query3 = "/jcr:root/test//*[propa=10]";
- assertEventually(() -> assertQuery(query3, XPATH, Arrays.asList("/test/test2", "/test/test3")));
+ assertEventually(() -> assertQuery(query3, XPATH, List.of("/test/test2", "/test/test3")));
}
@Test
@@ -769,11 +772,11 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
// Test query returns correct node on querying on dateProp
String query = "/jcr:root/test//*[propDate='2021-01-22T01:02:03.000Z']";
- assertEventually(() -> assertQuery(query, XPATH, Arrays.asList("/test/test1")));
+ assertEventually(() -> assertQuery(query, XPATH, List.of("/test/test1")));
// Test query returns correct node on querying on String type property
String query2 = "/jcr:root/test//*[propa='foo']";
- assertEventually(() -> assertQuery(query2, XPATH, Arrays.asList("/test/test1", "/test/test2")));
+ assertEventually(() -> assertQuery(query2, XPATH, List.of("/test/test1", "/test/test2")));
}
@Test
@@ -789,7 +792,7 @@ public abstract class IndexQueryCommonTest extends AbstractQueryTest {
// Test query returns correct node on querying on dateProp
String query = "/jcr:root/test//*[propa='foo'] order by @propDate descending";
- assertEventually(() -> assertQuery(query, XPATH, Arrays.asList("/test/test1", "/test/test3", "/test/test2"), true, true));
+ assertEventually(() -> assertQuery(query, XPATH, List.of("/test/test1", "/test/test3", "/test/test2"), true, true));
}
private static Tree child(Tree t, String n, String type) {