From 60a27dc56d279f8843d81c039eb6dc0973898f25 Mon Sep 17 00:00:00 2001 From: bfindlay Date: Mon, 20 Nov 2023 13:58:41 +1100 Subject: [PATCH 1/6] add flat object support Signed-off-by: bfindlay --- ...dProperty.java => FlatObjectProperty.java} | 30 +++++++++---------- .../opensearch/_types/mapping/Property.java | 20 ++++++------- .../_types/mapping/PropertyBuilders.java | 6 ++-- .../integTest/AbstractIndicesClientIT.java | 25 ++++++++++++++++ 4 files changed, 53 insertions(+), 28 deletions(-) rename java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/{FlattenedProperty.java => FlatObjectProperty.java} (90%) diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FlattenedProperty.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FlatObjectProperty.java similarity index 90% rename from java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FlattenedProperty.java rename to java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FlatObjectProperty.java index f683b158a1..fc21564e65 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FlattenedProperty.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FlatObjectProperty.java @@ -42,10 +42,10 @@ import org.opensearch.client.json.ObjectDeserializer; import org.opensearch.client.util.ObjectBuilder; -// typedef: _types.mapping.FlattenedProperty +// typedef: _types.mapping.FlatObjectProperty @JsonpDeserializable -public class FlattenedProperty extends PropertyBase implements PropertyVariant { +public class FlatObjectProperty extends PropertyBase implements PropertyVariant { @Nullable private final Double boost; @@ -75,7 +75,7 @@ public class FlattenedProperty extends PropertyBase implements PropertyVariant { // --------------------------------------------------------------------------------------------- - private FlattenedProperty(Builder builder) { + private FlatObjectProperty(Builder builder) { super(builder); this.boost = builder.boost; @@ -90,7 +90,7 @@ private FlattenedProperty(Builder builder) { } - public static FlattenedProperty of(Function> fn) { + public static FlatObjectProperty of(Function> fn) { return fn.apply(new Builder()).build(); } @@ -99,7 +99,7 @@ public static FlattenedProperty of(Function implements ObjectBuilder { + public static class Builder extends PropertyBase.AbstractBuilder implements ObjectBuilder { @Nullable private Double boost; @@ -337,29 +337,29 @@ protected Builder self() { } /** - * Builds a {@link FlattenedProperty}. + * Builds a {@link FlatObjectProperty}. * * @throws NullPointerException * if some of the required fields are null. */ - public FlattenedProperty build() { + public FlatObjectProperty build() { _checkSingleUse(); - return new FlattenedProperty(this); + return new FlatObjectProperty(this); } } // --------------------------------------------------------------------------------------------- /** - * Json deserializer for {@link FlattenedProperty} + * Json deserializer for {@link FlatObjectProperty} */ - public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( Builder::new, - FlattenedProperty::setupFlattenedPropertyDeserializer + FlatObjectProperty::setupFlatObjectPropertyDeserializer ); - protected static void setupFlattenedPropertyDeserializer(ObjectDeserializer op) { + protected static void setupFlatObjectPropertyDeserializer(ObjectDeserializer op) { PropertyBase.setupPropertyBaseDeserializer(op); op.add(Builder::boost, JsonpDeserializer.doubleDeserializer(), "boost"); op.add(Builder::depthLimit, JsonpDeserializer.integerDeserializer(), "depth_limit"); diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java index 5986748e90..4893f455ad 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java @@ -84,7 +84,7 @@ public enum Kind implements JsonEnum { Alias("alias"), - Flattened("flattened"), + FlatObject("flat_object"), Float("float"), @@ -404,8 +404,8 @@ public FieldAliasProperty alias() { /** * Is this variant instance of kind {@code flattened}? */ - public boolean isFlattened() { - return _kind == Kind.Flattened; + public boolean isFlatObject() { + return _kind == Kind.FlatObject; } /** @@ -414,8 +414,8 @@ public boolean isFlattened() { * @throws IllegalStateException * if the current variant is not of the {@code flattened} kind. */ - public FlattenedProperty flattened() { - return TaggedUnionUtils.get(this, Kind.Flattened); + public FlatObjectProperty flatObject() { + return TaggedUnionUtils.get(this, Kind.FlatObject); } /** @@ -1098,14 +1098,14 @@ public ObjectBuilder alias(Function flattened(FlattenedProperty v) { - this._kind = Kind.Flattened; + public ObjectBuilder flatObject(FlatObjectProperty v) { + this._kind = Kind.FlatObject; this._value = v; return this; } - public ObjectBuilder flattened(Function> fn) { - return this.flattened(fn.apply(new FlattenedProperty.Builder()).build()); + public ObjectBuilder flatObject(Function> fn) { + return this.flatObject(fn.apply(new FlatObjectProperty.Builder()).build()); } public ObjectBuilder float_(FloatNumberProperty v) { @@ -1457,7 +1457,7 @@ protected static void setupPropertyDeserializer(ObjectDeserializer op) op.add(Builder::double_, DoubleNumberProperty._DESERIALIZER, "double"); op.add(Builder::doubleRange, DoubleRangeProperty._DESERIALIZER, "double_range"); op.add(Builder::alias, FieldAliasProperty._DESERIALIZER, "alias"); - op.add(Builder::flattened, FlattenedProperty._DESERIALIZER, "flattened"); + op.add(Builder::flatObject, FlatObjectProperty._DESERIALIZER, "flat_object"); op.add(Builder::float_, FloatNumberProperty._DESERIALIZER, "float"); op.add(Builder::floatRange, FloatRangeProperty._DESERIALIZER, "float_range"); op.add(Builder::geoPoint, GeoPointProperty._DESERIALIZER, "geo_point"); diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/PropertyBuilders.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/PropertyBuilders.java index c519d4afc4..ae7f542eca 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/PropertyBuilders.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/PropertyBuilders.java @@ -134,11 +134,11 @@ public static FieldAliasProperty.Builder alias() { } /** - * Creates a builder for the {@link FlattenedProperty flattened} + * Creates a builder for the {@link FlatObjectProperty flatObject} * {@code Property} variant. */ - public static FlattenedProperty.Builder flattened() { - return new FlattenedProperty.Builder(); + public static FlatObjectProperty.Builder flatObject() { + return new FlatObjectProperty.Builder(); } /** diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractIndicesClientIT.java b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractIndicesClientIT.java index a3f360d245..8642f3a6c2 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractIndicesClientIT.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractIndicesClientIT.java @@ -12,9 +12,15 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import org.junit.Test; +import org.opensearch.Version; import org.opensearch.client.opensearch.OpenSearchAsyncClient; import org.opensearch.client.opensearch._types.OpenSearchException; +import org.opensearch.client.opensearch._types.mapping.FlatObjectProperty; +import org.opensearch.client.opensearch._types.mapping.Property; +import org.opensearch.client.opensearch.core.InfoResponse; import org.opensearch.client.opensearch.indices.CreateDataStreamResponse; +import org.opensearch.client.opensearch.indices.CreateIndexRequest; import org.opensearch.client.opensearch.indices.CreateIndexResponse; import org.opensearch.client.opensearch.indices.DataStream; import org.opensearch.client.opensearch.indices.DataStreamsStatsResponse; @@ -192,4 +198,23 @@ public void testGetNotExistingIndexAlias() throws Exception { assertEquals(ex.getMessage(), "Request failed: [string_error] " + "alias [alias_not_exists] missing"); } } + + @Test + public void createIndex_withFlatObject_IndexCreatesSucessfully() throws IOException { + InfoResponse info = javaClient().info(); + String version = info.version().number(); + if (version.contains("SNAPSHOT")) { + version = version.split("-")[0]; + } + assumeTrue("Flat Object is supported after version 2.7.0 only", Version.fromString(version).onOrAfter(Version.fromString("2.7.0"))); + try { + final CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index("flat-object-test") + .mappings(m -> m.properties("sample_flat_object", Property.of(p -> p.flatObject(new FlatObjectProperty.Builder().build())))) + .build(); + final CreateIndexResponse createIndexResponse = javaClient().indices().create(createIndexRequest); + assertTrue(createIndexResponse.acknowledged()); + } catch (OpenSearchException ex) { + fail(ex.getMessage()); + } + } } From 82b5035f79c50fa23cf306f58771b6e81ceae9b5 Mon Sep 17 00:00:00 2001 From: bfindlay Date: Mon, 20 Nov 2023 14:04:01 +1100 Subject: [PATCH 2/6] add flat object support Signed-off-by: bfindlay --- .../client/opensearch/_types/mapping/FieldType.java | 2 +- .../client/opensearch/_types/mapping/Property.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FieldType.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FieldType.java index ee1b6e052b..d2824ee1ee 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FieldType.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FieldType.java @@ -107,7 +107,7 @@ public enum FieldType implements JsonEnum { RankFeatures("rank_features"), - Flattened("flattened"), + FlatObject("flat_object"), Shape("shape"), diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java index 4893f455ad..9b338f295c 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java @@ -402,17 +402,17 @@ public FieldAliasProperty alias() { } /** - * Is this variant instance of kind {@code flattened}? + * Is this variant instance of kind {@code flat_oject}? */ public boolean isFlatObject() { return _kind == Kind.FlatObject; } /** - * Get the {@code flattened} variant value. + * Get the {@code flat_object} variant value. * * @throws IllegalStateException - * if the current variant is not of the {@code flattened} kind. + * if the current variant is not of the {@code flat_object} kind. */ public FlatObjectProperty flatObject() { return TaggedUnionUtils.get(this, Kind.FlatObject); From 0048b4024b1761bfb2d6e4267f478f8803e840e9 Mon Sep 17 00:00:00 2001 From: bfindlay Date: Mon, 20 Nov 2023 14:12:47 +1100 Subject: [PATCH 3/6] update changelog Signed-off-by: bfindlay --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1f7d7a0c3..d7287a7a6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ This section is for maintaining a changelog for all breaking changes for the cli ### Added - Added support for icu_collation_keyword type ([#725](https://github.com/opensearch-project/opensearch-java/pull/725)) +- Added support for flat_object field property ([#735](https://github.com/opensearch-project/opensearch-java/pull/735)) ### Dependencies From 10df60f3a7312b4cd89404372f493b4d68942985 Mon Sep 17 00:00:00 2001 From: bfindlay Date: Tue, 21 Nov 2023 14:19:19 +1100 Subject: [PATCH 4/6] update flatobject and user guides Signed-off-by: bfindlay --- USER_GUIDE.md | 13 + .../_types/mapping/FlatObjectProperty.java | 261 ------------------ .../integTest/AbstractIndicesClientIT.java | 41 ++- .../client/samples/FlatObjectBasics.java | 111 ++++++++ .../client/samples/util/IssueDocument.java | 94 +++++++ 5 files changed, 252 insertions(+), 268 deletions(-) create mode 100644 samples/src/main/java/org/opensearch/client/samples/FlatObjectBasics.java create mode 100644 samples/src/main/java/org/opensearch/client/samples/util/IssueDocument.java diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 4b21974f32..cce234bb3e 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -7,6 +7,7 @@ - [Creating an index](#creating-an-index) - [With default settings](#with-default-settings) - [With custom settings and mappings](#with-custom-settings-and-mappings) + - [With FlatObject mappings](#with-flat-object-mappings) - [Indexing data](#indexing-data) - [Searching for a document](#searching-for-a-document) - [Deleting a document](#deleting-a-document) @@ -136,6 +137,18 @@ CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder() .build(); client.indices().create(createIndexRequest); ``` +#### With flat object mappings +OpenSearch supports FlatObject mappings from version 2.7.0 without additional parameters. + +```java +final CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(indexName) + .mappings(m -> m.properties("issue", Property.of(p -> p.flatObject(new FlatObjectProperty.Builder().build())))) + .build(); +client.indices().create(createIndexRequest); +``` + +You can find a working sample of the above code in [FlatObjectBasics.java](./samples/src/main/java/org/opensearch/client/samples/FlatObjectBasics.java). + ### Indexing data diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FlatObjectProperty.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FlatObjectProperty.java index fc21564e65..bb317da753 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FlatObjectProperty.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FlatObjectProperty.java @@ -34,7 +34,6 @@ import jakarta.json.stream.JsonGenerator; import java.util.function.Function; -import javax.annotation.Nullable; import org.opensearch.client.json.JsonpDeserializable; import org.opensearch.client.json.JsonpDeserializer; import org.opensearch.client.json.JsonpMapper; @@ -46,48 +45,12 @@ @JsonpDeserializable public class FlatObjectProperty extends PropertyBase implements PropertyVariant { - @Nullable - private final Double boost; - - @Nullable - private final Integer depthLimit; - - @Nullable - private final Boolean docValues; - - @Nullable - private final Boolean eagerGlobalOrdinals; - - @Nullable - private final Boolean index; - - @Nullable - private final IndexOptions indexOptions; - - @Nullable - private final String nullValue; - - @Nullable - private final String similarity; - - @Nullable - private final Boolean splitQueriesOnWhitespace; // --------------------------------------------------------------------------------------------- private FlatObjectProperty(Builder builder) { super(builder); - this.boost = builder.boost; - this.depthLimit = builder.depthLimit; - this.docValues = builder.docValues; - this.eagerGlobalOrdinals = builder.eagerGlobalOrdinals; - this.index = builder.index; - this.indexOptions = builder.indexOptions; - this.nullValue = builder.nullValue; - this.similarity = builder.similarity; - this.splitQueriesOnWhitespace = builder.splitQueriesOnWhitespace; - } public static FlatObjectProperty of(Function> fn) { @@ -102,127 +65,10 @@ public Property.Kind _propertyKind() { return Property.Kind.FlatObject; } - /** - * API name: {@code boost} - */ - @Nullable - public final Double boost() { - return this.boost; - } - - /** - * API name: {@code depth_limit} - */ - @Nullable - public final Integer depthLimit() { - return this.depthLimit; - } - - /** - * API name: {@code doc_values} - */ - @Nullable - public final Boolean docValues() { - return this.docValues; - } - - /** - * API name: {@code eager_global_ordinals} - */ - @Nullable - public final Boolean eagerGlobalOrdinals() { - return this.eagerGlobalOrdinals; - } - - /** - * API name: {@code index} - */ - @Nullable - public final Boolean index() { - return this.index; - } - - /** - * API name: {@code index_options} - */ - @Nullable - public final IndexOptions indexOptions() { - return this.indexOptions; - } - - /** - * API name: {@code null_value} - */ - @Nullable - public final String nullValue() { - return this.nullValue; - } - - /** - * API name: {@code similarity} - */ - @Nullable - public final String similarity() { - return this.similarity; - } - - /** - * API name: {@code split_queries_on_whitespace} - */ - @Nullable - public final Boolean splitQueriesOnWhitespace() { - return this.splitQueriesOnWhitespace; - } - protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { generator.write("type", "flat_object"); super.serializeInternal(generator, mapper); - if (this.boost != null) { - generator.writeKey("boost"); - generator.write(this.boost); - - } - if (this.depthLimit != null) { - generator.writeKey("depth_limit"); - generator.write(this.depthLimit); - - } - if (this.docValues != null) { - generator.writeKey("doc_values"); - generator.write(this.docValues); - - } - if (this.eagerGlobalOrdinals != null) { - generator.writeKey("eager_global_ordinals"); - generator.write(this.eagerGlobalOrdinals); - - } - if (this.index != null) { - generator.writeKey("index"); - generator.write(this.index); - - } - if (this.indexOptions != null) { - generator.writeKey("index_options"); - this.indexOptions.serialize(generator, mapper); - } - if (this.nullValue != null) { - generator.writeKey("null_value"); - generator.write(this.nullValue); - - } - if (this.similarity != null) { - generator.writeKey("similarity"); - generator.write(this.similarity); - - } - if (this.splitQueriesOnWhitespace != null) { - generator.writeKey("split_queries_on_whitespace"); - generator.write(this.splitQueriesOnWhitespace); - - } - } // --------------------------------------------------------------------------------------------- @@ -232,104 +78,6 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { */ public static class Builder extends PropertyBase.AbstractBuilder implements ObjectBuilder { - @Nullable - private Double boost; - - @Nullable - private Integer depthLimit; - - @Nullable - private Boolean docValues; - - @Nullable - private Boolean eagerGlobalOrdinals; - - @Nullable - private Boolean index; - - @Nullable - private IndexOptions indexOptions; - - @Nullable - private String nullValue; - - @Nullable - private String similarity; - - @Nullable - private Boolean splitQueriesOnWhitespace; - - /** - * API name: {@code boost} - */ - public final Builder boost(@Nullable Double value) { - this.boost = value; - return this; - } - - /** - * API name: {@code depth_limit} - */ - public final Builder depthLimit(@Nullable Integer value) { - this.depthLimit = value; - return this; - } - - /** - * API name: {@code doc_values} - */ - public final Builder docValues(@Nullable Boolean value) { - this.docValues = value; - return this; - } - - /** - * API name: {@code eager_global_ordinals} - */ - public final Builder eagerGlobalOrdinals(@Nullable Boolean value) { - this.eagerGlobalOrdinals = value; - return this; - } - - /** - * API name: {@code index} - */ - public final Builder index(@Nullable Boolean value) { - this.index = value; - return this; - } - - /** - * API name: {@code index_options} - */ - public final Builder indexOptions(@Nullable IndexOptions value) { - this.indexOptions = value; - return this; - } - - /** - * API name: {@code null_value} - */ - public final Builder nullValue(@Nullable String value) { - this.nullValue = value; - return this; - } - - /** - * API name: {@code similarity} - */ - public final Builder similarity(@Nullable String value) { - this.similarity = value; - return this; - } - - /** - * API name: {@code split_queries_on_whitespace} - */ - public final Builder splitQueriesOnWhitespace(@Nullable Boolean value) { - this.splitQueriesOnWhitespace = value; - return this; - } @Override protected Builder self() { @@ -361,15 +109,6 @@ public FlatObjectProperty build() { protected static void setupFlatObjectPropertyDeserializer(ObjectDeserializer op) { PropertyBase.setupPropertyBaseDeserializer(op); - op.add(Builder::boost, JsonpDeserializer.doubleDeserializer(), "boost"); - op.add(Builder::depthLimit, JsonpDeserializer.integerDeserializer(), "depth_limit"); - op.add(Builder::docValues, JsonpDeserializer.booleanDeserializer(), "doc_values"); - op.add(Builder::eagerGlobalOrdinals, JsonpDeserializer.booleanDeserializer(), "eager_global_ordinals"); - op.add(Builder::index, JsonpDeserializer.booleanDeserializer(), "index"); - op.add(Builder::indexOptions, IndexOptions._DESERIALIZER, "index_options"); - op.add(Builder::nullValue, JsonpDeserializer.stringDeserializer(), "null_value"); - op.add(Builder::similarity, JsonpDeserializer.stringDeserializer(), "similarity"); - op.add(Builder::splitQueriesOnWhitespace, JsonpDeserializer.booleanDeserializer(), "split_queries_on_whitespace"); op.ignore("type"); } diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractIndicesClientIT.java b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractIndicesClientIT.java index 8642f3a6c2..11d7de218f 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractIndicesClientIT.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractIndicesClientIT.java @@ -31,6 +31,8 @@ import org.opensearch.client.opensearch.indices.GetIndexRequest; import org.opensearch.client.opensearch.indices.GetIndexResponse; import org.opensearch.client.opensearch.indices.GetIndicesSettingsRequest; +import org.opensearch.client.opensearch.indices.GetMappingRequest; +import org.opensearch.client.opensearch.indices.GetMappingResponse; import org.opensearch.client.opensearch.indices.IndexState; import org.opensearch.client.opensearch.indices.PutIndexTemplateResponse; import org.opensearch.common.settings.Settings; @@ -200,13 +202,9 @@ public void testGetNotExistingIndexAlias() throws Exception { } @Test - public void createIndex_withFlatObject_IndexCreatesSucessfully() throws IOException { - InfoResponse info = javaClient().info(); - String version = info.version().number(); - if (version.contains("SNAPSHOT")) { - version = version.split("-")[0]; - } - assumeTrue("Flat Object is supported after version 2.7.0 only", Version.fromString(version).onOrAfter(Version.fromString("2.7.0"))); + public void createIndex_withFlatObject_indexCreatesSuccessfully() throws IOException { + assumeFlatObjectSupport(); + try { final CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index("flat-object-test") .mappings(m -> m.properties("sample_flat_object", Property.of(p -> p.flatObject(new FlatObjectProperty.Builder().build())))) @@ -217,4 +215,33 @@ public void createIndex_withFlatObject_IndexCreatesSucessfully() throws IOExcept fail(ex.getMessage()); } } + + @Test + public void createIndex_withFlatObject_mappingCanBeRetrieved() throws IOException { + assumeFlatObjectSupport(); + + try { + final String indexName = "flat-object-mapping-index"; + final CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(indexName) + .mappings(m -> m.properties("sample_flat_object", Property.of(p -> p.flatObject(new FlatObjectProperty.Builder().build())))) + .build(); + final CreateIndexResponse createIndexResponse = javaClient().indices().create(createIndexRequest); + assertTrue(createIndexResponse.acknowledged()); + + final GetMappingResponse response = javaClient().indices().getMapping(GetMappingRequest.of(m -> m.index(indexName))); + final Property.Kind mappingKind = response.result().get(indexName).mappings().properties().get("sample_flat_object")._kind(); + assertEquals(mappingKind, Property.Kind.FlatObject); + } catch (OpenSearchException ex) { + fail(ex.getMessage()); + } + } + + private void assumeFlatObjectSupport() throws IOException { + InfoResponse info = javaClient().info(); + String version = info.version().number(); + if (version.contains("SNAPSHOT")) { + version = version.split("-")[0]; + } + assumeTrue("Flat Object is supported after version 2.7.0 only", Version.fromString(version).onOrAfter(Version.fromString("2.7.0"))); + } } diff --git a/samples/src/main/java/org/opensearch/client/samples/FlatObjectBasics.java b/samples/src/main/java/org/opensearch/client/samples/FlatObjectBasics.java new file mode 100644 index 0000000000..240e53c67e --- /dev/null +++ b/samples/src/main/java/org/opensearch/client/samples/FlatObjectBasics.java @@ -0,0 +1,111 @@ +package org.opensearch.client.samples; + +import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.client.opensearch._types.FieldValue; +import org.opensearch.client.opensearch._types.mapping.FlatObjectProperty; +import org.opensearch.client.opensearch._types.mapping.Property; +import org.opensearch.client.opensearch.core.IndexRequest; +import org.opensearch.client.opensearch.core.SearchRequest; +import org.opensearch.client.opensearch.core.SearchResponse; +import org.opensearch.client.opensearch.indices.CreateIndexRequest; +import org.opensearch.client.samples.util.IssueDocument; + +public class FlatObjectBasics { + private static final Logger LOGGER = LogManager.getLogger(IndexingBasics.class); + + public static void main(String[] args) { + try { + var client = SampleClient.create(); + + var version = client.info().version(); + LOGGER.info("Server: {}@{}", version.distribution(), version.number()); + + final var indexName = "flat_object-sample"; + + // Create a new index with an "issue" field with flat_object type + if (!client.indices().exists(e -> e.index(indexName)).value()) { + final CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(indexName) + .mappings(m -> m.properties("issue", Property.of(p -> p.flatObject(new FlatObjectProperty.Builder().build())))) + .build(); + client.indices().create(createIndexRequest); + } + + // Index some flat object documents + final IssueDocument issueDocument = new IssueDocument(); + final IssueDocument.Issue issue = new IssueDocument.Issue(); + issue.setNumber("123456"); + final IssueDocument.Labels labels = new IssueDocument.Labels(); + labels.setBackport(List.of("1.3", "2.0")); + labels.setVersion("2.1"); + final IssueDocument.Category category = new IssueDocument.Category(); + category.setType("API"); + category.setLevel("enhancement"); + + labels.setCategory(category); + issue.setLabels(labels); + + issueDocument.setIssue(issue); + final IndexRequest indexRequest = new IndexRequest.Builder().index(indexName) + .id("1") + .document(issueDocument) + .build(); + + client.index(indexRequest); + + // Index second document + final IssueDocument document2 = new IssueDocument(); + final IssueDocument.Issue issue2 = new IssueDocument.Issue(); + issue2.setNumber("123457"); + + IssueDocument.Labels labels2 = new IssueDocument.Labels(); + labels2.setVersion("2.2"); + + IssueDocument.Category category2 = new IssueDocument.Category(); + category2.setType("API"); + category2.setLevel("bug"); + + labels2.setCategory(category2); + issue2.setLabels(labels2); + + document2.setIssue(issue2); + + final IndexRequest indexRequest2 = new IndexRequest.Builder().index(indexName) + .id("2") + .document(document2) + .build(); + + client.index(indexRequest2); + + // wait for the document to index - as refresh period is set to 3s + Thread.sleep(3000); + + // Search for the documents + // Ref: https://opensearch.org/docs/latest/field-types/supported-field-types/flat-object/ + // Even if you don’t know the field names, you can search for a leaf value in the entire flat object. + // For example, the following request searches for all issues labeled as bugs + SearchRequest searchRequest = new SearchRequest.Builder().index(indexName) + .query(q -> q.match(m -> m.field("issue").query(FieldValue.of("bug")))) + .build(); + + SearchResponse searchResponse = client.search(searchRequest, IssueDocument.class); + for (var hit : searchResponse.hits().hits()) { + LOGGER.info("Found {} with score {}", hit.source(), hit.score()); + } + + // Alternatively, if you know the subfield name in which to search, provide the field’s path in dot notation + SearchRequest searchRequest2 = new SearchRequest.Builder().index(indexName) + .query(q -> q.match(m -> m.field("issue.labels.category.level").query(FieldValue.of("bug")))) + .build(); + + SearchResponse searchResponse2 = client.search(searchRequest2, IssueDocument.class); + for (var hit : searchResponse2.hits().hits()) { + LOGGER.info("Found {} with score {}", hit.source(), hit.score()); + } + + } catch (Exception e) { + LOGGER.error("Unexpected exception", e); + } + } +} diff --git a/samples/src/main/java/org/opensearch/client/samples/util/IssueDocument.java b/samples/src/main/java/org/opensearch/client/samples/util/IssueDocument.java new file mode 100644 index 0000000000..03f367019f --- /dev/null +++ b/samples/src/main/java/org/opensearch/client/samples/util/IssueDocument.java @@ -0,0 +1,94 @@ +package org.opensearch.client.samples.util; + +import java.util.List; + +public class IssueDocument { + + private Issue issue; + + // Getter and setter for "issue" + public Issue getIssue() { + return issue; + } + + public void setIssue(Issue issue) { + this.issue = issue; + } + + public static class Issue { + private String number; + private Labels labels; + + // Getters and setters for "number" and "labels" + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public Labels getLabels() { + return labels; + } + + public void setLabels(Labels labels) { + this.labels = labels; + } + + } + + public static class Labels { + private String version; + private List backport; + private Category category; + + // Getters and setters for "version", "backport", and "category" + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public List getBackport() { + return backport; + } + + public void setBackport(List backport) { + this.backport = backport; + } + + public Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } + + } + + public static class Category { + private String type; + private String level; + + // Getters and setters for "type" and "level" + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getLevel() { + return level; + } + + public void setLevel(String level) { + this.level = level; + } + } +} From dfbd85cc8cdce48417fdcab0f3bf2a886cd09dcf Mon Sep 17 00:00:00 2001 From: bfindlay Date: Tue, 21 Nov 2023 14:21:21 +1100 Subject: [PATCH 5/6] fix typo Signed-off-by: bfindlay --- .../opensearch/client/opensearch/_types/mapping/Property.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java index 9b338f295c..2634a090f4 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java @@ -402,7 +402,7 @@ public FieldAliasProperty alias() { } /** - * Is this variant instance of kind {@code flat_oject}? + * Is this variant instance of kind {@code flat_object}? */ public boolean isFlatObject() { return _kind == Kind.FlatObject; From 68da365f32bd54b88f1b76e7af5d29be7d540496 Mon Sep 17 00:00:00 2001 From: bfindlay Date: Tue, 21 Nov 2023 14:23:29 +1100 Subject: [PATCH 6/6] remove unused comments Signed-off-by: bfindlay --- .../org/opensearch/client/samples/util/IssueDocument.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/samples/src/main/java/org/opensearch/client/samples/util/IssueDocument.java b/samples/src/main/java/org/opensearch/client/samples/util/IssueDocument.java index 03f367019f..45e212ed1f 100644 --- a/samples/src/main/java/org/opensearch/client/samples/util/IssueDocument.java +++ b/samples/src/main/java/org/opensearch/client/samples/util/IssueDocument.java @@ -6,7 +6,6 @@ public class IssueDocument { private Issue issue; - // Getter and setter for "issue" public Issue getIssue() { return issue; } @@ -19,7 +18,6 @@ public static class Issue { private String number; private Labels labels; - // Getters and setters for "number" and "labels" public String getNumber() { return number; } @@ -43,7 +41,6 @@ public static class Labels { private List backport; private Category category; - // Getters and setters for "version", "backport", and "category" public String getVersion() { return version; } @@ -74,7 +71,6 @@ public static class Category { private String type; private String level; - // Getters and setters for "type" and "level" public String getType() { return type; }