diff --git a/CHANGELOG.md b/CHANGELOG.md index da05892150..2d2e37f499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased 2.x] ### Added +- Add support for knn_vector field type ([#529](https://github.com/opensearch-project/opensearch-java/pull/524)) ### Dependencies diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 9af0c5c166..b61cc105d7 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -6,11 +6,16 @@ - [Create a client](#create-a-client) - [Create a client using `RestClientTransport`](#create-a-client-using-restclienttransport) - [Create a client using `ApacheHttpClient5Transport`](#create-a-client-using-apachehttpclient5transport) - - [Create an index](#create-an-index) + - [Create an index](#create-an-index) + - [Create an index with default settings](#create-an-index-with-default-settings) + - [Create an index with custom settings and mappings](#create-an-index-with-custom-settings-and-mappings) - [Index data](#index-data) - [Search for the documents](#search-for-the-documents) - [Get raw JSON results](#get-raw-json-results) - [Search documents using a match query](#search-documents-using-a-match-query) + - [Search documents using k-NN](#search-documents-using-k-nn) + - [Exact k-NN with scoring script](#exact-k-nn-with-scoring-script) + - [Exact k-NN with painless scripting extension](#exact-k-nn-with-painless-scripting-extension) - [Search documents using suggesters](#search-documents-using-suggesters) - [App Data class](#app-data-class) - [Using completion suggester](#using-completion-suggester) @@ -84,7 +89,7 @@ There are multiple low level transports which `OpenSearchClient` could be config import org.apache.hc.core5.http.HttpHost; final HttpHost[] hosts = new HttpHost[] { - new HttpHost("localhost", "http", 9200) + new HttpHost("http", "localhost", 9200) }; // Initialize the client with SSL and TLS enabled @@ -112,7 +117,7 @@ Upcoming OpenSearch `3.0.0` release brings HTTP/2 support and as such, the `Rest import org.apache.hc.core5.http.HttpHost; final HttpHost[] hosts = new HttpHost[] { - new HttpHost("localhost", "http", 9200) + new HttpHost("http", "localhost", 9200) }; final OpenSearchTransport transport = ApacheHttpClient5TransportBuilder @@ -140,12 +145,33 @@ OpenSearchClient client = new OpenSearchClient(transport); ## Create an index +### Create an index with default settings + ```java String index = "sample-index"; CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build(); client.indices().create(createIndexRequest); ``` +### Create an index with custom settings and mappings + +```java +String index = "sample-index"; +IndexSettings settings = new IndexSettings.Builder() + .numberOfShards("2") + .numberOfReplicas("1") + .build(); +TypeMapping mapping = new TypeMapping.Builder() + .properties("age", new Property.Builder().integer(new IntegerNumberProperty.Builder().build()).build()) + .build(); +CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder() + .index(index) + .settings(settings) + .mappings(mapping) + .build(); +client.indices().create(createIndexRequest); +``` + ## Index data ```java @@ -191,6 +217,172 @@ for (int i = 0; i < searchResponse.hits().hits().size(); i++) { } ``` +## Search documents using k-NN + +### Exact k-NN with scoring script + +1. Create index with custom mapping + +```java +String index = "my-knn-index-1"; +TypeMapping mapping = new TypeMapping.Builder() + .properties("my_vector", new Property.Builder() + .knnVector(new KnnVectorProperty.Builder() + .dimension(4) + .build()) + .build()) + .build(); +CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder() + .index(index) + .mappings(mapping) + .build(); +client.indices().create(createIndexRequest); +``` + +2. Index documents + +```java +JsonObject doc1 = Json.createObjectBuilder() + .add("my_vector", Json.createArrayBuilder().add(1.5).add(5.5).add(4.5).add(6.4).build()) + .add("price", 10.3) + .build(); +JsonObject doc2 = Json.createObjectBuilder() + .add("my_vector", Json.createArrayBuilder().add(2.5).add(3.5).add(5.6).add(6.7).build()) + .add("price", 5.5) + .build(); +JsonObject doc3 = Json.createObjectBuilder() + .add("my_vector", Json.createArrayBuilder().add(4.5).add(5.5).add(6.7).add(3.7).build()) + .add("price", 4.4) + .build(); + +ArrayList operations = new ArrayList<>(); +operations.add(new BulkOperation.Builder().index( + IndexOperation.of(io -> io.index(index).id("1").document(doc1)) + ).build()); +operations.add(new BulkOperation.Builder().index( + IndexOperation.of(io -> io.index(index).id("2").document(doc2)) + ).build()); +operations.add(new BulkOperation.Builder().index( + IndexOperation.of(io -> io.index(index).id("3").document(doc3)) + ).build()); + +BulkRequest bulkRequest = new BulkRequest.Builder() + .index(index) + .operations(operations) + .build(); +client.bulk(bulkRequest); +``` + +3. Search documents using k-NN script score (_This implementation utilizes `com.fasterxml.jackson.databind.JsonNode` as the target document class, which is not part of the OpenSearch Java library. However, any document class that matches the searched data can be used instead._) + +```java +InlineScript inlineScript = new InlineScript.Builder() + .source("knn_score") + .lang("knn") + .params(Map.of( + "field", JsonData.of("my_vector"), + "query_value", JsonData.of(List.of(1.5, 5.5, 4.5, 6.4)), + "space_type", JsonData.of("cosinesimil") + )) + .build(); +Query query = new Query.Builder() + .scriptScore(new ScriptScoreQuery.Builder() + .query(new Query.Builder() + .matchAll(new MatchAllQuery.Builder().build()) + .build()) + .script(new Script.Builder() + .inline(inlineScript) + .build()) + .build()) + .build(); +SearchRequest searchRequest = new SearchRequest.Builder() + .index(index) + .query(query) + .build(); +SearchResponse searchResponse = client.search(searchRequest, JsonNode.class); +``` + +### Exact k-NN with painless scripting extension + +1. Create index with custom mapping + +```java +String index = "my-knn-index-1"; +TypeMapping mapping = new TypeMapping.Builder() + .properties("my_vector", new Property.Builder() + .knnVector(new KnnVectorProperty.Builder() + .dimension(4) + .build()) + .build()) + .build(); +CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder() + .index(index) + .mappings(mapping) + .build(); +client.indices().create(createIndexRequest); +``` + +2. Index documents + +```java +JsonObject doc1 = Json.createObjectBuilder() + .add("my_vector", Json.createArrayBuilder().add(1.5).add(5.5).add(4.5).add(6.4).build()) + .add("price", 10.3) + .build(); +JsonObject doc2 = Json.createObjectBuilder() + .add("my_vector", Json.createArrayBuilder().add(2.5).add(3.5).add(5.6).add(6.7).build()) + .add("price", 5.5) + .build(); +JsonObject doc3 = Json.createObjectBuilder() + .add("my_vector", Json.createArrayBuilder().add(4.5).add(5.5).add(6.7).add(3.7).build()) + .add("price", 4.4) + .build(); + +ArrayList operations = new ArrayList<>(); +operations.add(new BulkOperation.Builder().index( + IndexOperation.of(io -> io.index(index).id("1").document(doc1)) + ).build()); +operations.add(new BulkOperation.Builder().index( + IndexOperation.of(io -> io.index(index).id("2").document(doc2)) + ).build()); +operations.add(new BulkOperation.Builder().index( + IndexOperation.of(io -> io.index(index).id("3").document(doc3)) + ).build()); + +BulkRequest bulkRequest = new BulkRequest.Builder() + .index(index) + .operations(operations) + .build(); +client.bulk(bulkRequest); +``` + +3. Search documents using k-NN with painless scripting extension (_This implementation utilizes `com.fasterxml.jackson.databind.JsonNode` as the target document class, which is not part of the OpenSearch Java library. However, any document class that matches the searched data can be used instead._) + +```java +InlineScript inlineScript = new InlineScript.Builder() + .source("1.0 + cosineSimilarity(params.query_value, doc[params.field])") + .params(Map.of( + "field", JsonData.of("my_vector"), + "query_value", JsonData.of(List.of(1.5, 5.5, 4.5, 6.4)) + )) + .build(); +Query query = new Query.Builder() + .scriptScore(new ScriptScoreQuery.Builder() + .query(new Query.Builder() + .matchAll(new MatchAllQuery.Builder().build()) + .build()) + .script(new Script.Builder() + .inline(inlineScript) + .build()) + .build()) + .build(); +SearchRequest searchRequest = new SearchRequest.Builder() + .index(index) + .query(query) + .build(); +SearchResult searchResult = client.search(searchRequest, JsonNode.class); +``` + ## Search documents using suggesters ### App Data class diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/DenseVectorIndexOptions.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/DenseVectorIndexOptions.java deleted file mode 100644 index 5e5647730c..0000000000 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/DenseVectorIndexOptions.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * 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. - */ - -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -//---------------------------------------------------- -// THIS CODE IS GENERATED. MANUAL EDITS WILL BE LOST. -//---------------------------------------------------- - -package org.opensearch.client.opensearch._types.mapping; - -import org.opensearch.client.json.JsonpDeserializable; -import org.opensearch.client.json.JsonpDeserializer; -import org.opensearch.client.json.JsonpMapper; -import org.opensearch.client.json.JsonpSerializable; -import org.opensearch.client.json.ObjectBuilderDeserializer; -import org.opensearch.client.json.ObjectDeserializer; -import org.opensearch.client.util.ApiTypeHelper; -import org.opensearch.client.util.ObjectBuilder; -import org.opensearch.client.util.ObjectBuilderBase; -import jakarta.json.stream.JsonGenerator; -import java.util.function.Function; - -// typedef: _types.mapping.DenseVectorIndexOptions - -@JsonpDeserializable -public class DenseVectorIndexOptions implements JsonpSerializable { - private final String type; - - private final int m; - - private final int efConstruction; - - // --------------------------------------------------------------------------------------------- - - private DenseVectorIndexOptions(Builder builder) { - - this.type = ApiTypeHelper.requireNonNull(builder.type, this, "type"); - this.m = ApiTypeHelper.requireNonNull(builder.m, this, "m"); - this.efConstruction = ApiTypeHelper.requireNonNull(builder.efConstruction, this, "efConstruction"); - - } - - public static DenseVectorIndexOptions of(Function> fn) { - return fn.apply(new Builder()).build(); - } - - /** - * Required - API name: {@code type} - */ - public final String type() { - return this.type; - } - - /** - * Required - API name: {@code m} - */ - public final int m() { - return this.m; - } - - /** - * Required - API name: {@code ef_construction} - */ - public final int efConstruction() { - return this.efConstruction; - } - - /** - * Serialize this object to JSON. - */ - public void serialize(JsonGenerator generator, JsonpMapper mapper) { - generator.writeStartObject(); - serializeInternal(generator, mapper); - generator.writeEnd(); - } - - protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { - - generator.writeKey("type"); - generator.write(this.type); - - generator.writeKey("m"); - generator.write(this.m); - - generator.writeKey("ef_construction"); - generator.write(this.efConstruction); - - } - - // --------------------------------------------------------------------------------------------- - - /** - * Builder for {@link DenseVectorIndexOptions}. - */ - - public static class Builder extends ObjectBuilderBase implements ObjectBuilder { - private String type; - - private Integer m; - - private Integer efConstruction; - - /** - * Required - API name: {@code type} - */ - public final Builder type(String value) { - this.type = value; - return this; - } - - /** - * Required - API name: {@code m} - */ - public final Builder m(int value) { - this.m = value; - return this; - } - - /** - * Required - API name: {@code ef_construction} - */ - public final Builder efConstruction(int value) { - this.efConstruction = value; - return this; - } - - /** - * Builds a {@link DenseVectorIndexOptions}. - * - * @throws NullPointerException - * if some of the required fields are null. - */ - public DenseVectorIndexOptions build() { - _checkSingleUse(); - - return new DenseVectorIndexOptions(this); - } - } - - // --------------------------------------------------------------------------------------------- - - /** - * Json deserializer for {@link DenseVectorIndexOptions} - */ - public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer - .lazy(Builder::new, DenseVectorIndexOptions::setupDenseVectorIndexOptionsDeserializer); - - protected static void setupDenseVectorIndexOptionsDeserializer( - ObjectDeserializer op) { - - op.add(Builder::type, JsonpDeserializer.stringDeserializer(), "type"); - op.add(Builder::m, JsonpDeserializer.integerDeserializer(), "m"); - op.add(Builder::efConstruction, JsonpDeserializer.integerDeserializer(), "ef_construction"); - - } - -} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/DenseVectorProperty.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/DenseVectorProperty.java deleted file mode 100644 index 722b79de35..0000000000 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/DenseVectorProperty.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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. - */ - -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -//---------------------------------------------------- -// THIS CODE IS GENERATED. MANUAL EDITS WILL BE LOST. -//---------------------------------------------------- - -package org.opensearch.client.opensearch._types.mapping; - -import org.opensearch.client.json.JsonpDeserializable; -import org.opensearch.client.json.JsonpDeserializer; -import org.opensearch.client.json.JsonpMapper; -import org.opensearch.client.json.ObjectBuilderDeserializer; -import org.opensearch.client.json.ObjectDeserializer; -import org.opensearch.client.util.ApiTypeHelper; -import org.opensearch.client.util.ObjectBuilder; -import jakarta.json.stream.JsonGenerator; -import java.util.function.Function; -import javax.annotation.Nullable; - -// typedef: _types.mapping.DenseVectorProperty - - -@JsonpDeserializable -public class DenseVectorProperty extends PropertyBase implements PropertyVariant { - private final int dims; - - @Nullable - private final String similarity; - - @Nullable - private final Boolean index; - - @Nullable - private final DenseVectorIndexOptions indexOptions; - - // --------------------------------------------------------------------------------------------- - - private DenseVectorProperty(Builder builder) { - super(builder); - - this.dims = ApiTypeHelper.requireNonNull(builder.dims, this, "dims"); - this.similarity = builder.similarity; - this.index = builder.index; - this.indexOptions = builder.indexOptions; - - } - - public static DenseVectorProperty of(Function> fn) { - return fn.apply(new Builder()).build(); - } - - /** - * Property variant kind. - */ - @Override - public Property.Kind _propertyKind() { - return Property.Kind.DenseVector; - } - - /** - * Required - API name: {@code dims} - */ - public final int dims() { - return this.dims; - } - - /** - * API name: {@code similarity} - */ - @Nullable - public final String similarity() { - return this.similarity; - } - - /** - * API name: {@code index} - */ - @Nullable - public final Boolean index() { - return this.index; - } - - /** - * API name: {@code index_options} - */ - @Nullable - public final DenseVectorIndexOptions indexOptions() { - return this.indexOptions; - } - - protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { - - generator.write("type", "dense_vector"); - super.serializeInternal(generator, mapper); - generator.writeKey("dims"); - generator.write(this.dims); - - if (this.similarity != null) { - generator.writeKey("similarity"); - generator.write(this.similarity); - - } - if (this.index != null) { - generator.writeKey("index"); - generator.write(this.index); - - } - if (this.indexOptions != null) { - generator.writeKey("index_options"); - this.indexOptions.serialize(generator, mapper); - - } - - } - - // --------------------------------------------------------------------------------------------- - - /** - * Builder for {@link DenseVectorProperty}. - */ - - public static class Builder extends PropertyBase.AbstractBuilder - implements - ObjectBuilder { - private Integer dims; - - @Nullable - private String similarity; - - @Nullable - private Boolean index; - - @Nullable - private DenseVectorIndexOptions indexOptions; - - /** - * Required - API name: {@code dims} - */ - public final Builder dims(int value) { - this.dims = value; - return this; - } - - /** - * API name: {@code similarity} - */ - public final Builder similarity(@Nullable String value) { - this.similarity = 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 DenseVectorIndexOptions value) { - this.indexOptions = value; - return this; - } - - /** - * API name: {@code index_options} - */ - public final Builder indexOptions( - Function> fn) { - return this.indexOptions(fn.apply(new DenseVectorIndexOptions.Builder()).build()); - } - - @Override - protected Builder self() { - return this; - } - - /** - * Builds a {@link DenseVectorProperty}. - * - * @throws NullPointerException - * if some of the required fields are null. - */ - public DenseVectorProperty build() { - _checkSingleUse(); - - return new DenseVectorProperty(this); - } - } - - // --------------------------------------------------------------------------------------------- - - /** - * Json deserializer for {@link DenseVectorProperty} - */ - public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer - .lazy(Builder::new, DenseVectorProperty::setupDenseVectorPropertyDeserializer); - - protected static void setupDenseVectorPropertyDeserializer(ObjectDeserializer op) { - PropertyBase.setupPropertyBaseDeserializer(op); - op.add(Builder::dims, JsonpDeserializer.integerDeserializer(), "dims"); - op.add(Builder::similarity, JsonpDeserializer.stringDeserializer(), "similarity"); - op.add(Builder::index, JsonpDeserializer.booleanDeserializer(), "index"); - op.add(Builder::indexOptions, DenseVectorIndexOptions._DESERIALIZER, "index_options"); - - op.ignore("type"); - } - -} 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 a6620a1dda..07b2ac13b3 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 @@ -122,8 +122,7 @@ public enum FieldType implements JsonEnum { AggregateMetricDouble("aggregate_metric_double"), - DenseVector("dense_vector"), - + KnnVector("knn_vector"), ; private final String jsonValue; diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/KnnVectorMethod.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/KnnVectorMethod.java new file mode 100644 index 0000000000..af27ae1c80 --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/KnnVectorMethod.java @@ -0,0 +1,205 @@ +/* + * 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._types.mapping; + +import java.util.Map; +import java.util.function.Function; + +import javax.annotation.Nullable; + +import org.opensearch.client.json.JsonData; +import org.opensearch.client.json.JsonpDeserializable; +import org.opensearch.client.json.JsonpDeserializer; +import org.opensearch.client.json.JsonpMapper; +import org.opensearch.client.json.JsonpSerializable; +import org.opensearch.client.json.ObjectBuilderDeserializer; +import org.opensearch.client.json.ObjectDeserializer; +import org.opensearch.client.util.ApiTypeHelper; +import org.opensearch.client.util.ObjectBuilder; +import org.opensearch.client.util.ObjectBuilderBase; + +import jakarta.json.stream.JsonGenerator; + +// typedef: _types.mapping.KnnVectorMethod + +@JsonpDeserializable +public class KnnVectorMethod implements JsonpSerializable { + /** + * Builder for {@link KnnVectorMethod}. + */ + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + private String name; + + @Nullable + private String spaceType; + + @Nullable + private String engine; + + @Nullable + private Map parameters; + + /** + * Required - API name: {@code name} + */ + public final Builder name(String value) { + this.name = value; + return this; + } + + /** + * API name: {@code space_type} + */ + public final Builder spaceType(@Nullable String value) { + this.spaceType = value; + return this; + } + + /** + * API name: {@code engine} + */ + public final Builder engine(@Nullable String value) { + this.engine = value; + return this; + } + + /** + * API name: {@code parameters} + */ + public final Builder parameters(@Nullable Map map) { + this.parameters = _mapPutAll(this.parameters, map); + return this; + } + + /** + * Builds a {@link KnnVectorMethod}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public KnnVectorMethod build() { + _checkSingleUse(); + + return new KnnVectorMethod(this); + } + } + + /** + * Json deserializer for {@link KnnVectorMethod} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer + .lazy(Builder::new, KnnVectorMethod::setupKnnVectorMethodDeserializer); + + public static KnnVectorMethod of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + protected static void setupKnnVectorMethodDeserializer( + ObjectDeserializer op) { + + op.add(Builder::name, JsonpDeserializer.stringDeserializer(), "name"); + op.add(Builder::spaceType, JsonpDeserializer.stringDeserializer(), "space_type"); + op.add(Builder::engine, JsonpDeserializer.stringDeserializer(), "engine"); + op.add(Builder::parameters, JsonpDeserializer.stringMapDeserializer(JsonData._DESERIALIZER), "parameters"); + + } + + // --------------------------------------------------------------------------------------------- + + private final String name; + + @Nullable + private final String spaceType; + + @Nullable + private final String engine; + + @Nullable + private final Map parameters; + + private KnnVectorMethod(Builder builder) { + + this.name = ApiTypeHelper.requireNonNull(builder.name, this, "name"); + this.spaceType = builder.spaceType; + this.engine = builder.engine; + this.parameters = builder.parameters; + + } + + /** + * Required - API name: {@code name} + */ + public final String name() { + return this.name; + } + + /** + * API name: {@code space_type} + */ + @Nullable + public final String spaceType() { + return this.spaceType; + } + + /** + * API name: {@code engine} + */ + @Nullable + public final String engine() { + return this.engine; + } + + // --------------------------------------------------------------------------------------------- + + /** + * API name: {@code parameters} + */ + @Nullable + public final Map parameters() { + return this.parameters; + } + + // --------------------------------------------------------------------------------------------- + + /** + * Serialize this object to JSON. + */ + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + generator.writeStartObject(); + serializeInternal(generator, mapper); + generator.writeEnd(); + } + + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + + generator.writeKey("name"); + generator.write(this.name); + + if (this.spaceType != null) { + generator.writeKey("space_type"); + generator.write(this.spaceType); + } + + if (this.engine != null) { + generator.writeKey("engine"); + generator.write(this.engine); + } + + if (this.parameters != null) { + generator.writeKey("parameters"); + for (Map.Entry item0 : this.parameters.entrySet()) { + generator.writeKey(item0.getKey()); + item0.getValue().serialize(generator, mapper); + } + } + + } + +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/KnnVectorProperty.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/KnnVectorProperty.java new file mode 100644 index 0000000000..16a9ca6d3b --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/KnnVectorProperty.java @@ -0,0 +1,182 @@ +/* + * 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._types.mapping; + +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; +import org.opensearch.client.json.ObjectBuilderDeserializer; +import org.opensearch.client.json.ObjectDeserializer; +import org.opensearch.client.util.ApiTypeHelper; +import org.opensearch.client.util.ObjectBuilder; + +import jakarta.json.stream.JsonGenerator; + +// typedef: _types.mapping.KnnVectorProperty + +@JsonpDeserializable +public class KnnVectorProperty extends PropertyBase implements PropertyVariant { + /** + * Builder for {@link KnnVectorProperty}. + */ + + public static class Builder extends PropertyBase.AbstractBuilder + implements + ObjectBuilder { + private Integer dimension; + + @Nullable + private String modelId; + + @Nullable + private KnnVectorMethod method; + + /** + * Required - API name: {@code dimension} + */ + public final Builder dimension(int value) { + this.dimension = value; + return this; + } + + /** + * API name: {@code model_id} + */ + public final Builder modelId(@Nullable String value) { + this.modelId = value; + return this; + } + + /** + * API name: {@code method} + */ + public final Builder method(@Nullable KnnVectorMethod value) { + this.method = value; + return this; + } + + /** + * Builds a {@link KnnVectorProperty}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public KnnVectorProperty build() { + _checkSingleUse(); + + return new KnnVectorProperty(this); + } + + @Override + protected Builder self() { + return this; + } + } + + /** + * Json deserializer for {@link KnnVectorProperty} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer + .lazy(Builder::new, KnnVectorProperty::setupKnnVectorPropertyDeserializer); + + public static KnnVectorProperty of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + // --------------------------------------------------------------------------------------------- + + protected static void setupKnnVectorPropertyDeserializer(ObjectDeserializer op) { + PropertyBase.setupPropertyBaseDeserializer(op); + op.add(Builder::dimension, JsonpDeserializer.integerDeserializer(), "dimension"); + op.add(Builder::modelId, JsonpDeserializer.stringDeserializer(), "model_id"); + op.add(Builder::method, KnnVectorMethod._DESERIALIZER, "method"); + + op.ignore("type"); + } + + private final int dimension; + + @Nullable + private final String modelId; + + @Nullable + private final KnnVectorMethod method; + + private KnnVectorProperty(Builder builder) { + super(builder); + + this.dimension = ApiTypeHelper.requireNonNull(builder.dimension, this, "dimension"); + this.modelId = builder.modelId; + this.method = builder.method; + + } + + /** + * Property variant kind. + */ + @Override + public Property.Kind _propertyKind() { + return Property.Kind.KnnVector; + } + + /** + * Required - API name: {@code dimension} + */ + public final int dimension() { + return this.dimension; + } + + // --------------------------------------------------------------------------------------------- + + /** + * API name: {@code model_id} + */ + @Nullable + public final String modelId() { + return this.modelId; + } + + // --------------------------------------------------------------------------------------------- + + /** + * API name: {@code method} + */ + @Nullable + public final KnnVectorMethod method() { + return this.method; + } + + @Override + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + + generator.write("type", "knn_vector"); + super.serializeInternal(generator, mapper); + generator.writeKey("dimension"); + generator.write(this.dimension); + + if (this.modelId != null) { + + generator.writeKey("model_id"); + generator.write(this.modelId); + + } + + if (this.method != null) { + + generator.writeKey("method"); + this.method.serialize(generator, mapper); + } + + } + +} 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 6e2381ce82..9bff87715a 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,8 +84,6 @@ public enum Kind implements JsonEnum { DateRange("date_range"), - DenseVector("dense_vector"), - Double("double"), DoubleRange("double_range"), @@ -118,6 +116,8 @@ public enum Kind implements JsonEnum { Keyword("keyword"), + KnnVector("knn_vector"), + Long("long"), LongRange("long_range"), @@ -354,23 +354,6 @@ public DateRangeProperty dateRange() { return TaggedUnionUtils.get(this, Kind.DateRange); } - /** - * Is this variant instance of kind {@code dense_vector}? - */ - public boolean isDenseVector() { - return _kind == Kind.DenseVector; - } - - /** - * Get the {@code dense_vector} variant value. - * - * @throws IllegalStateException - * if the current variant is not of the {@code dense_vector} kind. - */ - public DenseVectorProperty denseVector() { - return TaggedUnionUtils.get(this, Kind.DenseVector); - } - /** * Is this variant instance of kind {@code double}? */ @@ -643,6 +626,19 @@ public KeywordProperty keyword() { return TaggedUnionUtils.get(this, Kind.Keyword); } + /** + * Is this variant instance of kind {@code knn_vector}? + */ + public boolean isKnnVector() { return _kind == Kind.KnnVector; } + + /** + * Get the {@code knn_vector} variant value. + * + * @throws IllegalStateException + * if the current variant is not of the {@code knn_vector} kind. + */ + public KnnVectorProperty knnVector() { return TaggedUnionUtils.get(this, Kind.KnnVector); } + /** * Is this variant instance of kind {@code long}? */ @@ -1057,17 +1053,6 @@ public ObjectBuilder dateRange( return this.dateRange(fn.apply(new DateRangeProperty.Builder()).build()); } - public ObjectBuilder denseVector(DenseVectorProperty v) { - this._kind = Kind.DenseVector; - this._value = v; - return this; - } - - public ObjectBuilder denseVector( - Function> fn) { - return this.denseVector(fn.apply(new DenseVectorProperty.Builder()).build()); - } - public ObjectBuilder double_(DoubleNumberProperty v) { this._kind = Kind.Double; this._value = v; @@ -1240,6 +1225,16 @@ public ObjectBuilder keyword(Function knnVector(KnnVectorProperty v) { + this._kind = Kind.KnnVector; + this._value = v; + return this; + } + + public ObjectBuilder knnVector(Function> fn) { + return this.knnVector(fn.apply(new KnnVectorProperty.Builder()).build()); + } + public ObjectBuilder long_(LongNumberProperty v) { this._kind = Kind.Long; this._value = v; @@ -1450,7 +1445,6 @@ protected static void setupPropertyDeserializer(ObjectDeserializer op) op.add(Builder::dateNanos, DateNanosProperty._DESERIALIZER, "date_nanos"); op.add(Builder::date, DateProperty._DESERIALIZER, "date"); op.add(Builder::dateRange, DateRangeProperty._DESERIALIZER, "date_range"); - op.add(Builder::denseVector, DenseVectorProperty._DESERIALIZER, "dense_vector"); op.add(Builder::double_, DoubleNumberProperty._DESERIALIZER, "double"); op.add(Builder::doubleRange, DoubleRangeProperty._DESERIALIZER, "double_range"); op.add(Builder::alias, FieldAliasProperty._DESERIALIZER, "alias"); @@ -1467,6 +1461,7 @@ protected static void setupPropertyDeserializer(ObjectDeserializer op) op.add(Builder::ipRange, IpRangeProperty._DESERIALIZER, "ip_range"); op.add(Builder::join, JoinProperty._DESERIALIZER, "join"); op.add(Builder::keyword, KeywordProperty._DESERIALIZER, "keyword"); + op.add(Builder::knnVector, KnnVectorProperty._DESERIALIZER, "knn_vector"); op.add(Builder::long_, LongNumberProperty._DESERIALIZER, "long"); op.add(Builder::longRange, LongRangeProperty._DESERIALIZER, "long_range"); op.add(Builder::murmur3, Murmur3HashProperty._DESERIALIZER, "murmur3"); 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 4c143e2e6a..4013fdf8b0 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 @@ -114,14 +114,6 @@ public static DateRangeProperty.Builder dateRange() { return new DateRangeProperty.Builder(); } - /** - * Creates a builder for the {@link DenseVectorProperty dense_vector} - * {@code Property} variant. - */ - public static DenseVectorProperty.Builder denseVector() { - return new DenseVectorProperty.Builder(); - } - /** * Creates a builder for the {@link DoubleNumberProperty double} * {@code Property} variant. @@ -248,6 +240,14 @@ public static KeywordProperty.Builder keyword() { return new KeywordProperty.Builder(); } + /** + * Creates a builder for the {@link KnnVectorProperty long} {@code Property} + * variant. + */ + public static KnnVectorProperty.Builder knnVector() { + return new KnnVectorProperty.Builder(); + } + /** * Creates a builder for the {@link LongNumberProperty long} {@code Property} * variant. diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettings.java b/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettings.java index bae7d418cb..4b7e26558d 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettings.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/indices/IndexSettings.java @@ -222,6 +222,12 @@ public class IndexSettings implements JsonpSerializable { @Nullable private final IndexSettingsMapping mapping; + @Nullable + private final Boolean knn; + + @Nullable + private final Integer knnAlgoParamEfSearch; + // --------------------------------------------------------------------------------------------- private IndexSettings(Builder builder) { @@ -282,6 +288,8 @@ private IndexSettings(Builder builder) { this.analysis = builder.analysis; this.settings = builder.settings; this.mapping = builder.mapping; + this.knn = builder.knn; + this.knnAlgoParamEfSearch = builder.knnAlgoParamEfSearch; } @@ -736,6 +744,22 @@ public final IndexSettingsMapping mapping() { return this.mapping; } + /** + * API name: {@code knn} + */ + @Nullable + public final Boolean knn() { + return this.knn; + } + + /** + * API name: {@code knn.algo_param.ef_search} + */ + @Nullable + public final Integer knnAlgoParamEfSearch() { + return this.knnAlgoParamEfSearch; + } + /** * Serialize this object to JSON. */ @@ -1032,6 +1056,16 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { this.mapping.serialize(generator, mapper); } + if (this.knn != null) { + generator.writeKey("knn"); + generator.write(this.knn); + + } + if (this.knnAlgoParamEfSearch != null) { + generator.writeKey("knn.algo_param_ef_search"); + generator.write(this.knnAlgoParamEfSearch); + + } } @@ -1210,6 +1244,12 @@ public static class Builder extends ObjectBuilderBase implements ObjectBuilder