diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ed98c93cf..acea6880ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Fixed - Fix version and build ([#254](https://github.com/opensearch-project/opensearch-java/pull/254)) - Fixed Suggesters for Completion, Term, and Phrase and refactored the Suggestion class ([#477](https://github.com/opensearch-project/opensearch-java/pull/477)) +- Fix highlight max_analyzer_offset field name to match with the one introduced in OpenSearch 2.2.0 ([#555](https://github.com/opensearch-project/opensearch-java/pull/555)) ### Security diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/search/Highlight.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/search/Highlight.java index 5c9c22c67d..20cabf1393 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/core/search/Highlight.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/search/Highlight.java @@ -112,7 +112,7 @@ public class Highlight implements JsonpSerializable { private final Query highlightQuery; @Nullable - private final String maxAnalyzedOffset; + private final String maxAnalyzerOffset; // --------------------------------------------------------------------------------------------- @@ -137,7 +137,7 @@ private Highlight(Builder builder) { this.requireFieldMatch = builder.requireFieldMatch; this.tagsSchema = builder.tagsSchema; this.highlightQuery = builder.highlightQuery; - this.maxAnalyzedOffset = builder.maxAnalyzedOffset; + this.maxAnalyzerOffset = builder.maxAnalyzerOffset; } @@ -295,11 +295,11 @@ public final Query highlightQuery() { } /** - * API name: {@code max_analyzed_offset} + * API name: {@code max_analyzer_offset} */ @Nullable - public final String maxAnalyzedOffset() { - return this.maxAnalyzedOffset; + public final String maxAnalyzerOffset() { + return this.maxAnalyzerOffset; } /** @@ -419,9 +419,9 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { this.highlightQuery.serialize(generator, mapper); } - if (this.maxAnalyzedOffset != null) { - generator.writeKey("max_analyzed_offset"); - generator.write(this.maxAnalyzedOffset); + if (this.maxAnalyzerOffset != null) { + generator.writeKey("max_analyzer_offset"); + generator.write(this.maxAnalyzerOffset); } @@ -491,7 +491,7 @@ public static class Builder extends ObjectBuilderBase implements ObjectBuilder } /** - * API name: {@code max_analyzed_offset} + * API name: {@code max_analyzer_offset} */ - public final Builder maxAnalyzedOffset(@Nullable String value) { - this.maxAnalyzedOffset = value; + public final Builder maxAnalyzerOffset(@Nullable String value) { + this.maxAnalyzerOffset = value; return this; } @@ -756,7 +756,7 @@ protected static void setupHighlightDeserializer(ObjectDeserializer>> highlights = highlightQuery("spread", + h -> h.fields("content", b -> b)); + + assertEquals(2, highlights.size()); + for (Map> hit : highlights) { + assertEquals(1, hit.size()); + assertEquals(1, hit.get("content").size()); + assertTrue(hit.get("content").get(0).contains("spread")); + } + } + + @Test + public void testMultiFieldHighlight() throws Exception { + String index = "queries_highlight"; + createTestDocuments(index); + + List>> highlights = highlightQuery("real decades", + h -> h.fields("title", b -> b).fields("content", b -> b)); + + assertEquals(3, highlights.size()); + for (Map> hit : highlights) { + assertEquals(2, hit.size()); + assertEquals(1, hit.get("title").size()); + assertTrue(hit.get("title").get(0).contains("Real")); + assertEquals(1, hit.get("content").size()); + assertTrue(hit.get("content").get(0).contains("decades")); + } + } + + @Test + public void testDifferentMarkersHighlight() throws Exception { + String index = "queries_highlight"; + createTestDocuments(index); + + List>> highlights = highlightQuery("spread", + h -> h.preTags("").postTags("").fields("content", b -> b)); + + assertEquals(2, highlights.size()); + for (Map> hit : highlights) { + assertEquals(1, hit.size()); + assertEquals(1, hit.get("content").size()); + assertTrue(hit.get("content").get(0).contains("spread")); + } + } + + @Test + public void testAnalyzerOffset() throws Exception { + + String[] versionNumber = javaClient().info().version().number().split("\\."); + int major = Integer.parseInt(versionNumber[0]); + int minor = Integer.parseInt(versionNumber[1]); + + // The max_analyzer_offset setting was introduced in OpenSearch 2.2.0 + // before that, the max_analyzer_offset thrown an unknown field exception + // For more details, see: + // https://github.com/opensearch-project/OpenSearch/pull/4031 + // https://github.com/opensearch-project/OpenSearch/pull/3893 + if (major >= 2 && minor >= 2) { + String index = "queries_highlight"; + createTestDocuments(index); + List>> highlights = highlightQuery("real", + h -> h.maxAnalyzerOffset("5").fields("title", b -> b)); + + assertEquals(3, highlights.size()); + assertEquals(0, highlights.get(0).size()); + assertEquals(1, highlights.get(1).size()); + assertEquals(1, highlights.get(2).size()); + + assertTrue(highlights.get(1).get("title").get(0).contains("Real")); + assertTrue(highlights.get(2).get("title").get(0).contains("Real")); + } + } + + private List>> highlightQuery(String query, + Function> fn) + throws IOException { + SearchResponse
response = javaClient() + .search(s -> s + .query(q -> q + .simpleQueryString(sqs -> sqs + .fields("title", "content", "author") + .query(query))) + .highlight(fn), Article.class); + return response.hits().hits().stream().map(Hit::highlight).collect(Collectors.toList()); + } + + private void createTestDocuments(String index) throws IOException { + javaClient().create(_1 -> _1.index(index).id("1").document(createArticle( + "Superheroes are Real", "Meet these man avoid the fire spread during last decades.", "John Doe")) + .refresh(Refresh.True)); + javaClient().create(_1 -> _1.index(index).id("2").document(createArticle( + "Real Slow Ideas", "Why some innovations spread quick while others take decades to catch hold.", "John Foo")) + .refresh(Refresh.True)); + javaClient().create(_1 -> _1.index(index).id("3").document(createArticle( + "Real Two Degrees", "How the world failed on climate change during the decades.", "Anne Doe")) + .refresh(Refresh.True)); + } + + private Article createArticle(String title, String content, String author) { + return new Article(title, content, author); + } + + public static class Article { + public String title; + public String content; + public String author; + + public Article() { + } + + public Article(String title, String content, String author) { + this.title = title; + this.content = content; + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(final String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(final String content) { + this.content = content; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(final String author) { + this.author = author; + } + } + +} diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/httpclient5/HighlightIT.java b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/httpclient5/HighlightIT.java new file mode 100644 index 0000000000..1f097e2497 --- /dev/null +++ b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/httpclient5/HighlightIT.java @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.client.opensearch.integTest.httpclient5; + +import org.opensearch.client.opensearch.integTest.AbstractHighlightIT; + +public class HighlightIT extends AbstractHighlightIT implements HttpClient5TransportSupport { +} diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/restclient/HighlightIT.java b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/restclient/HighlightIT.java new file mode 100644 index 0000000000..e16c26712c --- /dev/null +++ b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/restclient/HighlightIT.java @@ -0,0 +1,26 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.client.opensearch.integTest.restclient; + +import org.apache.hc.core5.http.HttpHost; +import org.opensearch.client.json.jackson.JacksonJsonpMapper; +import org.opensearch.client.opensearch.integTest.AbstractHighlightIT; +import org.opensearch.client.transport.OpenSearchTransport; +import org.opensearch.client.transport.rest_client.RestClientTransport; +import org.opensearch.common.settings.Settings; + +import java.io.IOException; + +public class HighlightIT extends AbstractHighlightIT { + @Override + public OpenSearchTransport buildTransport(Settings settings, HttpHost[] hosts) throws IOException { + return new RestClientTransport(buildClient(settings, hosts), new JacksonJsonpMapper()); + } + +}