From ff851033d9bf470951ce406bd933f7b4be9dc057 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 8 Apr 2026 14:35:48 +0200 Subject: [PATCH 1/2] feat(gh-518): add multi2multivec-weaviate module --- .../v1/api/collections/VectorConfig.java | 42 +++++- .../Multi2MultiVecWeaviateVectorizer.java | 124 ++++++++++++++++++ .../client6/v1/internal/json/JSONTest.java | 23 ++++ 3 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/VectorConfig.java b/src/main/java/io/weaviate/client6/v1/api/collections/VectorConfig.java index b615ac7c1..7d1624ad8 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/VectorConfig.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/VectorConfig.java @@ -17,6 +17,7 @@ import io.weaviate.client6.v1.api.collections.vectorizers.Img2VecNeuralVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2MultiVecJinaAiVectorizer; +import io.weaviate.client6.v1.api.collections.vectorizers.Multi2MultiVecWeaviateVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecAwsVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecBindVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecClipVectorizer; @@ -78,7 +79,8 @@ public enum Kind implements JsonEnum { MULTI2VEC_NVIDIA("multi2vec-nvidia"), MULTI2VEC_VOYAGEAI("multi2vec-voyageai"), TEXT2MULTIVEC_JINAAI("text2multivec-jinaai"), - MULTI2MULTIVEC_JINAAI("multi2multivec-jinaai"); + MULTI2MULTIVEC_JINAAI("multi2multivec-jinaai"), + MULTI2MULTIVEC_WEAVIATE("multi2multivec-weaviate"); private static final Map jsonValueMap = JsonEnum.collectNames(Kind.values()); private final String jsonValue; @@ -208,6 +210,43 @@ public static Map.Entry multi2multivecJinaai(String vector return Map.entry(vectorName, Multi2MultiVecJinaAiVectorizer.of(fn)); } + /** Create a vector index with an {@code multi2multivec-weaviate} vectorizer. */ + public static Map.Entry multi2multivecWeaviate() { + return multi2multivecWeaviate(VectorIndex.DEFAULT_VECTOR_NAME); + } + + /** + * Create a vector index with an {@code multi2multivec-weaviate} vectorizer. + * + * @param fn Lambda expression for optional parameters. + */ + public static Map.Entry multi2multivecWeaviate( + Function> fn) { + return multi2multivecWeaviate(VectorIndex.DEFAULT_VECTOR_NAME, fn); + } + + /** + * Create a named vector index with an {@code multi2multivec-weaviate} + * vectorizer. + * + * @param vectorName Vector name. + */ + public static Map.Entry multi2multivecWeaviate(String vectorName) { + return Map.entry(vectorName, Multi2MultiVecWeaviateVectorizer.of()); + } + + /** + * Create a named vector index with an {@code multi2multivec-weaviate} + * vectorizer. + * + * @param vectorName Vector name. + * @param fn Lambda expression for optional parameters. + */ + public static Map.Entry multi2multivecWeaviate(String vectorName, + Function> fn) { + return Map.entry(vectorName, Multi2MultiVecWeaviateVectorizer.of(fn)); + } + /** Create a vector index with an {@code multi2vec-aws} vectorizer. */ public static Map.Entry multi2vecAws() { return multi2vecAws(VectorIndex.DEFAULT_VECTOR_NAME); @@ -1650,6 +1689,7 @@ private final void init(Gson gson) { addAdapter(gson, VectorConfig.Kind.MULTI2VEC_VOYAGEAI, Multi2VecVoyageAiVectorizer.class); addAdapter(gson, VectorConfig.Kind.TEXT2MULTIVEC_JINAAI, Text2MultiVecJinaAiVectorizer.class); addAdapter(gson, VectorConfig.Kind.MULTI2MULTIVEC_JINAAI, Multi2MultiVecJinaAiVectorizer.class); + addAdapter(gson, VectorConfig.Kind.MULTI2MULTIVEC_WEAVIATE, Multi2MultiVecWeaviateVectorizer.class); } @SuppressWarnings("unchecked") diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java b/src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java new file mode 100644 index 000000000..4df31e136 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java @@ -0,0 +1,124 @@ +package io.weaviate.client6.v1.api.collections.vectorizers; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +import com.google.gson.annotations.SerializedName; + +import io.weaviate.client6.v1.api.collections.Quantization; +import io.weaviate.client6.v1.api.collections.VectorConfig; +import io.weaviate.client6.v1.api.collections.VectorIndex; +import io.weaviate.client6.v1.internal.ObjectBuilder; + +public record Multi2MultiVecWeaviateVectorizer( + /** Base URL of the embedding service. */ + @SerializedName("baseURL") String baseUrl, + /** Inference model to use. */ + @SerializedName("model") String model, + /** BLOB properties included in the embedding. */ + @SerializedName("imageFields") List imageFields, + /** TEXT properties included in the embedding. */ + @SerializedName("textFields") List textFields, + /** Vector index configuration. */ + VectorIndex vectorIndex, + /** Vector quantization method. */ + Quantization quantization) implements VectorConfig { + + @Override + public VectorConfig.Kind _kind() { + return VectorConfig.Kind.MULTI2MULTIVEC_WEAVIATE; + } + + @Override + public Object _self() { + return this; + } + + /** ColBERT-family model available in the Weaviate Embedding Service. */ + public static String MODERNVBERT_COLMODERNVBERT = "ModernVBERT/colmodernvbert"; + + public static Multi2MultiVecWeaviateVectorizer of() { + return of(ObjectBuilder.identity()); + } + + public static Multi2MultiVecWeaviateVectorizer of( + Function> fn) { + return fn.apply(new Builder()).build(); + } + + public Multi2MultiVecWeaviateVectorizer(Builder builder) { + this( + builder.baseUrl, + builder.model, + builder.imageFields, + builder.textFields, + builder.vectorIndex, + builder.quantization); + } + + public static class Builder implements ObjectBuilder { + private VectorIndex vectorIndex = VectorIndex.DEFAULT_VECTOR_INDEX; + private Quantization quantization; + + private String baseUrl; + private String model; + + private List imageFields; + private List textFields; + + public Builder baseUrl(String baseUrl) { + this.baseUrl = baseUrl; + return this; + } + + public Builder model(String model) { + this.model = model; + return this; + } + + /** Add BLOB properties to include in the embedding. */ + public Builder imageFields(List fields) { + imageFields = fields; + return this; + } + + /** Add BLOB properties to include in the embedding. */ + public Builder imageFields(String... fields) { + return imageFields(Arrays.asList(fields)); + } + + /** Add TEXT properties to include in the embedding. */ + public Builder textFields(List fields) { + textFields = fields; + return this; + } + + /** Add TEXT properties to include in the embedding. */ + public Builder textFields(String... fields) { + return textFields(Arrays.asList(fields)); + } + + /** + * Override default vector index configuration. + * + * HNSW + * is the default vector index. + */ + public Builder vectorIndex(VectorIndex vectorIndex) { + this.vectorIndex = vectorIndex; + return this; + } + + public Builder quantization(Quantization quantization) { + this.quantization = quantization; + return this; + } + + @Override + public Multi2MultiVecWeaviateVectorizer build() { + return new Multi2MultiVecWeaviateVectorizer(this); + } + } +} diff --git a/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java b/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java index ffb39f6cd..36b80a460 100644 --- a/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java +++ b/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java @@ -40,6 +40,7 @@ import io.weaviate.client6.v1.api.collections.vectorindex.MultiVector.Aggregation; import io.weaviate.client6.v1.api.collections.vectorizers.Img2VecNeuralVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2MultiVecJinaAiVectorizer; +import io.weaviate.client6.v1.api.collections.vectorizers.Multi2MultiVecWeaviateVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecAwsVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecClipVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecCohereVectorizer; @@ -632,6 +633,28 @@ public static Object[][] testCases() { } """, }, + { + VectorConfig.class, + Multi2MultiVecWeaviateVectorizer.of(v -> v + .baseUrl("example.com") + .model(Multi2MultiVecWeaviateVectorizer.MODERNVBERT_COLMODERNVBERT) + .imageFields("a", "b") + .textFields("c")), + """ + { + "vectorIndexType": "hnsw", + "vectorIndexConfig": {}, + "vectorizer": { + "multi2multivec-weaviate": { + "baseURL": "example.com", + "model": "ModernVBERT/colmodernvbert", + "imageFields": ["a", "b"], + "textFields": ["c"] + } + } + } + """, + }, { VectorConfig.class, Multi2VecClipVectorizer.of(v -> v.imageFields("a", "b").textFields("c")), From 9af365a4e9cb101c4e41a1097bcb6424ea39951a Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 8 Apr 2026 15:24:34 +0200 Subject: [PATCH 2/2] fix(config): remove textFields from multi2multivec-weaviate --- .../Multi2MultiVecWeaviateVectorizer.java | 15 -------------- .../client6/v1/internal/json/JSONTest.java | 20 ++++++++++++++----- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java b/src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java index 4df31e136..5cb07c921 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java @@ -18,8 +18,6 @@ public record Multi2MultiVecWeaviateVectorizer( @SerializedName("model") String model, /** BLOB properties included in the embedding. */ @SerializedName("imageFields") List imageFields, - /** TEXT properties included in the embedding. */ - @SerializedName("textFields") List textFields, /** Vector index configuration. */ VectorIndex vectorIndex, /** Vector quantization method. */ @@ -52,7 +50,6 @@ public Multi2MultiVecWeaviateVectorizer(Builder builder) { builder.baseUrl, builder.model, builder.imageFields, - builder.textFields, builder.vectorIndex, builder.quantization); } @@ -65,7 +62,6 @@ public static class Builder implements ObjectBuilder imageFields; - private List textFields; public Builder baseUrl(String baseUrl) { this.baseUrl = baseUrl; @@ -88,17 +84,6 @@ public Builder imageFields(String... fields) { return imageFields(Arrays.asList(fields)); } - /** Add TEXT properties to include in the embedding. */ - public Builder textFields(List fields) { - textFields = fields; - return this; - } - - /** Add TEXT properties to include in the embedding. */ - public Builder textFields(String... fields) { - return textFields(Arrays.asList(fields)); - } - /** * Override default vector index configuration. * diff --git a/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java b/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java index 36b80a460..6f7abf2aa 100644 --- a/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java +++ b/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java @@ -79,7 +79,6 @@ import io.weaviate.client6.v1.api.rbac.UsersPermission; import io.weaviate.client6.v1.api.rbac.groups.GroupType; -/** Unit tests for custom POJO-to-JSON serialization. */ @RunWith(JParamsTestRunner.class) public class JSONTest { public static Object[][] testCases() { @@ -638,8 +637,7 @@ public static Object[][] testCases() { Multi2MultiVecWeaviateVectorizer.of(v -> v .baseUrl("example.com") .model(Multi2MultiVecWeaviateVectorizer.MODERNVBERT_COLMODERNVBERT) - .imageFields("a", "b") - .textFields("c")), + .imageFields("a", "b")), """ { "vectorIndexType": "hnsw", @@ -648,13 +646,25 @@ public static Object[][] testCases() { "multi2multivec-weaviate": { "baseURL": "example.com", "model": "ModernVBERT/colmodernvbert", - "imageFields": ["a", "b"], - "textFields": ["c"] + "imageFields": ["a", "b"] } } } """, }, + { + VectorConfig.class, + Multi2MultiVecWeaviateVectorizer.of(), + """ + { + "vectorIndexType": "hnsw", + "vectorIndexConfig": {}, + "vectorizer": { + "multi2multivec-weaviate": { } + } + } + """, + }, { VectorConfig.class, Multi2VecClipVectorizer.of(v -> v.imageFields("a", "b").textFields("c")),