From 07234f0f6345e97f3befb50ef6e3135e9438f707 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Mon, 2 Jun 2025 15:00:19 +0200 Subject: [PATCH 1/6] feat: support add_vectors operation (sync/async) --- .../client/v1/async/schema/Schema.java | 23 +++-- .../v1/async/schema/api/VectorAdder.java | 95 +++++++++++++++++++ .../io/weaviate/client/v1/schema/Schema.java | 5 + .../client/v1/schema/api/VectorAdder.java | 66 +++++++++++++ 4 files changed, 181 insertions(+), 8 deletions(-) create mode 100644 src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java create mode 100644 src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java diff --git a/src/main/java/io/weaviate/client/v1/async/schema/Schema.java b/src/main/java/io/weaviate/client/v1/async/schema/Schema.java index e6f9a7157..1b95e9357 100644 --- a/src/main/java/io/weaviate/client/v1/async/schema/Schema.java +++ b/src/main/java/io/weaviate/client/v1/async/schema/Schema.java @@ -1,5 +1,7 @@ package io.weaviate.client.v1.async.schema; +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; + import io.weaviate.client.Config; import io.weaviate.client.base.util.DbVersionSupport; import io.weaviate.client.v1.async.schema.api.ClassCreator; @@ -7,20 +9,19 @@ import io.weaviate.client.v1.async.schema.api.ClassExists; import io.weaviate.client.v1.async.schema.api.ClassGetter; import io.weaviate.client.v1.async.schema.api.ClassUpdater; -import io.weaviate.client.v1.async.schema.api.SchemaGetter; import io.weaviate.client.v1.async.schema.api.PropertyCreator; import io.weaviate.client.v1.async.schema.api.SchemaDeleter; -import io.weaviate.client.v1.async.schema.api.ShardsGetter; +import io.weaviate.client.v1.async.schema.api.SchemaGetter; import io.weaviate.client.v1.async.schema.api.ShardUpdater; +import io.weaviate.client.v1.async.schema.api.ShardsGetter; import io.weaviate.client.v1.async.schema.api.ShardsUpdater; import io.weaviate.client.v1.async.schema.api.TenantsCreator; -import io.weaviate.client.v1.async.schema.api.TenantsGetter; -import io.weaviate.client.v1.async.schema.api.TenantsUpdater; import io.weaviate.client.v1.async.schema.api.TenantsDeleter; import io.weaviate.client.v1.async.schema.api.TenantsExists; - +import io.weaviate.client.v1.async.schema.api.TenantsGetter; +import io.weaviate.client.v1.async.schema.api.TenantsUpdater; +import io.weaviate.client.v1.async.schema.api.VectorAdder; import io.weaviate.client.v1.auth.provider.AccessTokenProvider; -import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; public class Schema { private final CloseableHttpAsyncClient client; @@ -28,7 +29,8 @@ public class Schema { private final AccessTokenProvider tokenProvider; private final DbVersionSupport dbVersionSupport; - public Schema(CloseableHttpAsyncClient client, Config config, AccessTokenProvider tokenProvider, DbVersionSupport dbVersionSupport) { + public Schema(CloseableHttpAsyncClient client, Config config, AccessTokenProvider tokenProvider, + DbVersionSupport dbVersionSupport) { this.client = client; this.config = config; this.tokenProvider = tokenProvider; @@ -63,8 +65,13 @@ public PropertyCreator propertyCreator() { return new PropertyCreator(client, config, tokenProvider); } + public VectorAdder vectorAdder() { + return new VectorAdder(client, config, tokenProvider); + } + public SchemaDeleter allDeleter() { - return new SchemaDeleter(new SchemaGetter(client, config, tokenProvider), new ClassDeleter(client, config, tokenProvider)); + return new SchemaDeleter(new SchemaGetter(client, config, tokenProvider), + new ClassDeleter(client, config, tokenProvider)); } public ShardsGetter shardsGetter() { diff --git a/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java b/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java new file mode 100644 index 000000000..c9f6cecea --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java @@ -0,0 +1,95 @@ +package io.weaviate.client.v1.async.schema.api; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.core5.concurrent.FutureCallback; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpResponse; + +import io.weaviate.client.Config; +import io.weaviate.client.base.AsyncBaseClient; +import io.weaviate.client.base.AsyncClientResult; +import io.weaviate.client.base.Response; +import io.weaviate.client.base.Result; +import io.weaviate.client.base.http.async.ResponseParser; +import io.weaviate.client.base.util.UrlEncoder; +import io.weaviate.client.v1.auth.provider.AccessTokenProvider; +import io.weaviate.client.v1.schema.model.WeaviateClass; +import io.weaviate.client.v1.schema.model.WeaviateClass.VectorConfig; + +public class VectorAdder extends AsyncBaseClient implements AsyncClientResult { + private final ClassGetter getter; + + private String className; + private Map addedVectors = new HashMap<>(); + + public VectorAdder(CloseableHttpAsyncClient client, Config config, AccessTokenProvider tokenProvider) { + super(client, config, tokenProvider); + this.getter = new ClassGetter(client, config, tokenProvider); + } + + public VectorAdder withClass(String className) { + this.className = className; + return this; + } + + /** + * Add a named vectors. This method can be chained to add multiple named vectors + * without using a {@link Map}. + */ + public VectorAdder withVector(String name, VectorConfig vector) { + this.addedVectors.put(name, vector); + return this; + } + + /** + * Add all vectors from the map. This will overwrite any vectors added + * previously. + */ + public VectorAdder withVector(Map vectors) { + this.addedVectors = Map.copyOf(vectors); + return this; + } + + @Override + public Future> run(FutureCallback> callback) { + CompletableFuture> getClass = CompletableFuture.supplyAsync(() -> { + try { + return getter.withClassName(className).run().get(); + } catch (InterruptedException | ExecutionException e) { + throw new CompletionException(e); + } + }); + CompletableFuture> addVectors = getClass.>thenApplyAsync(result -> { + if (result.getError() != null) { + return result.toErrorResult(); + } + WeaviateClass cls = result.getResult(); + addedVectors.entrySet().stream() + .forEach(vector -> cls.getVectorConfig() + .putIfAbsent(vector.getKey(), vector.getValue())); + + String path = String.format("/schema/%s", UrlEncoder.encodePathParam(className)); + try { + return sendPutRequest(path, cls, callback, new ResponseParser() { + + @Override + public Result parse(HttpResponse response, String body, ContentType contentType) { + Response resp = this.serializer.toResponse(response.getCode(), body, WeaviateClass.class); + return new Result<>(response.getCode(), response.getCode() <= 299, resp.getErrors()); + } + }).get(); + } catch (InterruptedException | ExecutionException e) { + throw new CompletionException(e); + } + }); + + return addVectors; + } +} diff --git a/src/main/java/io/weaviate/client/v1/schema/Schema.java b/src/main/java/io/weaviate/client/v1/schema/Schema.java index 7614e578d..8dde3d5ba 100644 --- a/src/main/java/io/weaviate/client/v1/schema/Schema.java +++ b/src/main/java/io/weaviate/client/v1/schema/Schema.java @@ -19,6 +19,7 @@ import io.weaviate.client.v1.schema.api.TenantsExists; import io.weaviate.client.v1.schema.api.TenantsGetter; import io.weaviate.client.v1.schema.api.TenantsUpdater; +import io.weaviate.client.v1.schema.api.VectorAdder; public class Schema { private final Config config; @@ -59,6 +60,10 @@ public PropertyCreator propertyCreator() { return new PropertyCreator(httpClient, config); } + public VectorAdder vectorAdder() { + return new VectorAdder(httpClient, config); + } + public SchemaDeleter allDeleter() { return new SchemaDeleter(new SchemaGetter(httpClient, config), new ClassDeleter(httpClient, config)); } diff --git a/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java b/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java new file mode 100644 index 000000000..42a165edf --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java @@ -0,0 +1,66 @@ +package io.weaviate.client.v1.schema.api; + +import java.util.HashMap; +import java.util.Map; + +import io.weaviate.client.Config; +import io.weaviate.client.base.BaseClient; +import io.weaviate.client.base.ClientResult; +import io.weaviate.client.base.Response; +import io.weaviate.client.base.Result; +import io.weaviate.client.base.http.HttpClient; +import io.weaviate.client.base.util.UrlEncoder; +import io.weaviate.client.v1.schema.model.WeaviateClass; +import io.weaviate.client.v1.schema.model.WeaviateClass.VectorConfig; + +public class VectorAdder extends BaseClient implements ClientResult { + private final ClassGetter getter; + + private String className; + private Map addedVectors = new HashMap<>(); + + public VectorAdder(HttpClient httpClient, Config config) { + super(httpClient, config); + this.getter = new ClassGetter(httpClient, config); + } + + public VectorAdder withClass(String className) { + this.className = className; + return this; + } + + /** + * Add a named vectors. This method can be chained to add multiple named vectors + * without using a {@link Map}. + */ + public VectorAdder withVector(String name, VectorConfig vector) { + this.addedVectors.put(name, vector); + return this; + } + + /** + * Add all vectors from the map. This will overwrite any vectors added + * previously. + */ + public VectorAdder withVector(Map vectors) { + this.addedVectors = Map.copyOf(vectors); + return this; + } + + @Override + public Result run() { + Result result = getter.withClassName(className).run(); + if (result.hasErrors()) { + result.toErrorResult(); + } + + WeaviateClass cls = result.getResult(); + addedVectors.entrySet().stream() + .forEach(vector -> cls.getVectorConfig() + .putIfAbsent(vector.getKey(), vector.getValue())); + + String path = String.format("/schema/%s", UrlEncoder.encodePathParam(className)); + Response resp = sendPutRequest(path, cls, WeaviateClass.class); + return new Result<>(resp.getStatusCode(), resp.getStatusCode() == 200, resp.getErrors()); + } +} From 226247d580162ff02f3af4f8ad2d16cfbfe36add Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Mon, 2 Jun 2025 16:58:28 +0200 Subject: [PATCH 2/6] test: update target Weaviate version and add integration tests --- .../v1/async/schema/api/VectorAdder.java | 3 +- .../client/v1/schema/api/VectorAdder.java | 3 +- .../integration/client/WeaviateVersion.java | 7 +- .../client/async/schema/ClientSchemaTest.java | 170 +++++---- .../client/schema/ClientSchemaTest.java | 336 ++++++++---------- 5 files changed, 259 insertions(+), 260 deletions(-) diff --git a/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java b/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java index c9f6cecea..3fa95177d 100644 --- a/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java +++ b/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java @@ -1,5 +1,6 @@ package io.weaviate.client.v1.async.schema.api; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -53,7 +54,7 @@ public VectorAdder withVector(String name, VectorConfig vector) { * previously. */ public VectorAdder withVector(Map vectors) { - this.addedVectors = Map.copyOf(vectors); + this.addedVectors = Collections.unmodifiableMap(vectors); return this; } diff --git a/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java b/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java index 42a165edf..5fcc71bbf 100644 --- a/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java +++ b/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java @@ -1,5 +1,6 @@ package io.weaviate.client.v1.schema.api; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -43,7 +44,7 @@ public VectorAdder withVector(String name, VectorConfig vector) { * previously. */ public VectorAdder withVector(Map vectors) { - this.addedVectors = Map.copyOf(vectors); + this.addedVectors = Collections.unmodifiableMap(vectors); return this; } diff --git a/src/test/java/io/weaviate/integration/client/WeaviateVersion.java b/src/test/java/io/weaviate/integration/client/WeaviateVersion.java index 5b1c1381a..358cd29d5 100644 --- a/src/test/java/io/weaviate/integration/client/WeaviateVersion.java +++ b/src/test/java/io/weaviate/integration/client/WeaviateVersion.java @@ -3,12 +3,13 @@ public class WeaviateVersion { // docker image version - public static final String WEAVIATE_IMAGE = "1.31.0-rc.0-5ff7495"; + public static final String WEAVIATE_IMAGE = "1.31.0"; // to be set according to weaviate docker image - public static final String EXPECTED_WEAVIATE_VERSION = "1.31.0-rc.0"; + public static final String EXPECTED_WEAVIATE_VERSION = "1.31.0"; // to be set according to weaviate docker image public static final String EXPECTED_WEAVIATE_GIT_HASH = "5ff7495"; - private WeaviateVersion() {} + private WeaviateVersion() { + } } diff --git a/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java b/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java index c09668109..cf72439b1 100644 --- a/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java +++ b/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java @@ -1,5 +1,29 @@ package io.weaviate.integration.client.async.schema; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.InstanceOfAssertFactories.MAP; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.hc.core5.concurrent.FutureCallback; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; + import io.weaviate.client.Config; import io.weaviate.client.WeaviateClient; import io.weaviate.client.base.Result; @@ -17,29 +41,9 @@ import io.weaviate.client.v1.schema.model.ShardStatuses; import io.weaviate.client.v1.schema.model.Tokenization; import io.weaviate.client.v1.schema.model.WeaviateClass; +import io.weaviate.client.v1.schema.model.WeaviateClass.VectorConfig; import io.weaviate.integration.client.WeaviateDockerCompose; import io.weaviate.integration.tests.schema.SchemaTestSuite; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import org.apache.hc.core5.concurrent.FutureCallback; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.InstanceOfAssertFactories.MAP; -import org.junit.After; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.jupiter.api.Assertions.assertFalse; - -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; public class ClientSchemaTest { private WeaviateClient syncClient; @@ -83,8 +87,7 @@ public void testSchemaCreateBandClass() throws ExecutionException, InterruptedEx // given WeaviateClass clazz = SchemaTestSuite.testSchemaCreateBandClass.clazz; // when - Future> createStatusFuture = - client.schema().classCreator().withClass(clazz).run(); + Future> createStatusFuture = client.schema().classCreator().withClass(clazz).run(); Result createStatus = createStatusFuture.get(); Future> schemaFuture = client.schema().getter().run(); Result schema = schemaFuture.get(); @@ -130,7 +133,8 @@ public void failed(Exception e) { } @Override - public void cancelled() {} + public void cancelled() { + } }).get(); client.schema().classCreator().withClass(chickenSoup) .run(new FutureCallback>() { @@ -190,7 +194,6 @@ public void cancelled() { } }).get(); - client.schema().getter().run(new FutureCallback>() { @Override public void completed(Result schemaResult) { @@ -219,10 +222,8 @@ public void testSchemaDeleteAllSchema() throws ExecutionException, InterruptedEx WeaviateClass pizza = SchemaTestSuite.testSchemaDeleteAllSchema.pizza; WeaviateClass chickenSoup = SchemaTestSuite.testSchemaDeleteAllSchema.chickenSoup; // when - Result pizzaCreateStatus = - client.schema().classCreator().withClass(pizza).run().get(); - Result chickenSoupCreateStatus = - client.schema().classCreator().withClass(chickenSoup).run().get(); + Result pizzaCreateStatus = client.schema().classCreator().withClass(pizza).run().get(); + Result chickenSoupCreateStatus = client.schema().classCreator().withClass(chickenSoup).run().get(); Result schemaAfterCreate = client.schema().getter().run().get(); Result deleteAllStatus = client.schema().allDeleter().run().get(); Result schemaAfterDelete = client.schema().getter().run().get(); @@ -241,10 +242,8 @@ public void testSchemaCreateClassesAddProperties() WeaviateClass chickenSoup = SchemaTestSuite.testSchemaCreateClassesAddProperties.chickenSoup; Property newProperty = SchemaTestSuite.testSchemaCreateClassesAddProperties.newProperty; // when - Result pizzaCreateStatus = - client.schema().classCreator().withClass(pizza).run().get(); - Result chickenSoupCreateStatus = - client.schema().classCreator().withClass(chickenSoup).run().get(); + Result pizzaCreateStatus = client.schema().classCreator().withClass(pizza).run().get(); + Result chickenSoupCreateStatus = client.schema().classCreator().withClass(chickenSoup).run().get(); Result pizzaPropertyCreateStatus = client.schema().propertyCreator() .withProperty(newProperty).withClassName(pizza.getClassName()).run().get(); Result chickenSoupPropertyCreateStatus = client.schema().propertyCreator() @@ -260,6 +259,62 @@ public void testSchemaCreateClassesAddProperties() } } + @Test + public void testSchemaAddVectors() throws ExecutionException, InterruptedException { + // Arrange + VectorConfig vector = VectorConfig.builder() + .vectorIndexType("hnsw") + .vectorizer(Collections.singletonMap("none", Collections.emptyMap())) + .vectorIndexConfig(VectorIndexConfig.builder().build()) + .build(); + String className = "Pizza_testSchemaAddVectors"; + try (WeaviateAsyncClient client = syncClient.async()) { + client.schema().classCreator() + .withClass(WeaviateClass.builder() + .className(className) + .properties(Collections.singletonList( + Property.builder() + .name("title").dataType(Collections.singletonList(DataType.TEXT)) + .build())) + .vectorConfig(Collections.singletonMap("default", vector)) + .build()) + .run().get(); + + // Act + AtomicBoolean completed = new AtomicBoolean(false); + FutureCallback> callback = new FutureCallback>() { + + @Override + public void completed(Result result) { + completed.set(true); + } + + @Override + public void failed(Exception ex) { + completed.set(true); + } + + @Override + public void cancelled() { + } + }; + Result add = client.schema().vectorAdder() + .withClass(className) + .withVector("vector-a", vector) + .withVector("vector-b", vector) + .run(callback).get(); + assertNull("error adding new vectors", add.getError()); + + Result result = client.schema().classGetter() + .withClassName(className).run().get(); + WeaviateClass pizza = result.getResult(); + assertThat(pizza.getVectorConfig()) + .as("has all 3 vectors") + .containsKeys("default", "vector-a", "vector-b"); + assertTrue("callback called on completion", completed.get()); + } + } + @Test public void testSchemaCreateClassExplicitVectorizerWithProperties() throws ExecutionException, InterruptedException { @@ -440,19 +495,17 @@ public void testSchemaCreateClassWithInvalidTokenizationProperty() .description("A delicious religion like food and arguably the best export of Italy.") .build(); - Property notExistingTokenization = - Property.builder().dataType(Collections.singletonList(DataType.TEXT)) - .description("someString").name("someString").tokenization("not-existing").build(); - Property notSupportedTokenizationForInt = - Property.builder().dataType(Collections.singletonList(DataType.INT)) - .description("someInt").name("someInt").tokenization(Tokenization.WORD).build(); + Property notExistingTokenization = Property.builder().dataType(Collections.singletonList(DataType.TEXT)) + .description("someString").name("someString").tokenization("not-existing").build(); + Property notSupportedTokenizationForInt = Property.builder().dataType(Collections.singletonList(DataType.INT)) + .description("someInt").name("someInt").tokenization(Tokenization.WORD).build(); // when Result createStatus = client.schema().classCreator().withClass(pizza).run().get(); Result notExistingTokenizationCreateStatus = client.schema().propertyCreator() .withProperty(notExistingTokenization).withClassName(pizza.getClassName()).run().get(); - Result notSupportedTokenizationForIntCreateStatus = - client.schema().propertyCreator().withProperty(notSupportedTokenizationForInt) - .withClassName(pizza.getClassName()).run().get(); + Result notSupportedTokenizationForIntCreateStatus = client.schema().propertyCreator() + .withProperty(notSupportedTokenizationForInt) + .withClassName(pizza.getClassName()).run().get(); // then assertResultTrue(createStatus); @@ -474,10 +527,9 @@ public void testSchemaGetBandClass() throws ExecutionException, InterruptedExcep .vectorizer("text2vec-contextionary").build(); // when Result createStatus = client.schema().classCreator().withClass(clazz).run().get(); - Result bandClass = - client.schema().classGetter().withClassName(clazz.getClassName()).run().get(); - Result nonExistentClass = - client.schema().classGetter().withClassName("nonExistentClass").run().get(); + Result bandClass = client.schema().classGetter().withClassName(clazz.getClassName()).run().get(); + Result nonExistentClass = client.schema().classGetter().withClassName("nonExistentClass").run() + .get(); // then assertNotNull(createStatus); assertTrue(createStatus.getResult()); @@ -503,18 +555,15 @@ public void testSchemaGetShards() throws ExecutionException, InterruptedExceptio .vectorizer("text2vec-contextionary").build(); // when Result createStatus = client.schema().classCreator().withClass(clazz).run().get(); - Result bandClassExists = - client.schema().exists().withClassName(clazz.getClassName()).run().get(); - Result nonExistentClassExists = - client.schema().exists().withClassName("nonExistentClass").run().get(); + Result bandClassExists = client.schema().exists().withClassName(clazz.getClassName()).run().get(); + Result nonExistentClassExists = client.schema().exists().withClassName("nonExistentClass").run().get(); // then assertResultTrue(createStatus); assertResultTrue(bandClassExists); assertNotNull(nonExistentClassExists); assertFalse(nonExistentClassExists.getResult()); assertNull(nonExistentClassExists.getError()); - Result shards = - client.schema().shardsGetter().withClassName(clazz.getClassName()).run().get(); + Result shards = client.schema().shardsGetter().withClassName(clazz.getClassName()).run().get(); assertNotNull(shards); assertNotNull(shards.getResult()); assertEquals(1, shards.getResult().length); @@ -532,18 +581,15 @@ public void shouldUpdateClass() throws ExecutionException, InterruptedException Property.builder().name("question").dataType(Arrays.asList(DataType.TEXT)).build(), Property.builder().name("answer").dataType(Arrays.asList(DataType.TEXT)).build()); - WeaviateClass jeopardyClass = - WeaviateClass.builder().className(className).description("A Jeopardy! question") - .vectorizer("text2vec-contextionary").properties(properties).build(); + WeaviateClass jeopardyClass = WeaviateClass.builder().className(className).description("A Jeopardy! question") + .vectorizer("text2vec-contextionary").properties(properties).build(); - Result createResult = - client.schema().classCreator().withClass(jeopardyClass).run().get(); + Result createResult = client.schema().classCreator().withClass(jeopardyClass).run().get(); assertThat(createResult).isNotNull().withFailMessage(() -> createResult.getError().toString()) .returns(false, Result::hasErrors).withFailMessage(null).returns(true, Result::getResult); - Result createdClassResult = - client.schema().classGetter().withClassName(className).run().get(); + Result createdClassResult = client.schema().classGetter().withClassName(className).run().get(); assertThat(createdClassResult).isNotNull() .withFailMessage(() -> createdClassResult.getError().toString()) @@ -561,14 +607,12 @@ public void shouldUpdateClass() throws ExecutionException, InterruptedException .deletionStrategy(ReplicationConfig.DeletionStrategy.DELETE_ON_CONFLICT).build()) .build(); - Result updateResult = - client.schema().classUpdater().withClass(newJeopardyClass).run().get(); + Result updateResult = client.schema().classUpdater().withClass(newJeopardyClass).run().get(); assertThat(updateResult).isNotNull().withFailMessage(() -> updateResult.getError().toString()) .returns(false, Result::hasErrors).withFailMessage(null).returns(true, Result::getResult); - Result updatedClassResult = - client.schema().classGetter().withClassName(className).run().get(); + Result updatedClassResult = client.schema().classGetter().withClassName(className).run().get(); assertThat(updatedClassResult).isNotNull() .withFailMessage(() -> updatedClassResult.getError().toString()) diff --git a/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java b/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java index 009d26ab5..611a3c239 100644 --- a/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java +++ b/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java @@ -1,6 +1,30 @@ package io.weaviate.integration.client.schema; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; + import com.google.gson.Gson; + import io.weaviate.client.Config; import io.weaviate.client.WeaviateClient; import io.weaviate.client.base.Result; @@ -23,30 +47,9 @@ import io.weaviate.client.v1.schema.model.ShardStatuses; import io.weaviate.client.v1.schema.model.Tokenization; import io.weaviate.client.v1.schema.model.WeaviateClass; +import io.weaviate.client.v1.schema.model.WeaviateClass.VectorConfig; import io.weaviate.integration.client.WeaviateDockerCompose; import io.weaviate.integration.tests.schema.SchemaTestSuite; -import java.io.File; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.InstanceOfAssertFactories.MAP; -import org.junit.After; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; - public class ClientSchemaTest { private WeaviateClient client; @@ -101,13 +104,11 @@ public void testSchemaDeleteClasses() { WeaviateClass chickenSoup = SchemaTestSuite.testSchemaDeleteClasses.chickenSoup; // when Result pizzaCreateStatus = client.schema().classCreator().withClass(pizza).run(); - Result chickenSoupCreateStatus = - client.schema().classCreator().withClass(chickenSoup).run(); + Result chickenSoupCreateStatus = client.schema().classCreator().withClass(chickenSoup).run(); Result schemaAfterCreate = client.schema().getter().run(); - Result deletePizzaStatus = - client.schema().classDeleter().withClassName(pizza.getClassName()).run(); - Result deleteChickenSoupStatus = - client.schema().classDeleter().withClassName(chickenSoup.getClassName()).run(); + Result deletePizzaStatus = client.schema().classDeleter().withClassName(pizza.getClassName()).run(); + Result deleteChickenSoupStatus = client.schema().classDeleter().withClassName(chickenSoup.getClassName()) + .run(); Result schemaAfterDelete = client.schema().getter().run(); // then SchemaTestSuite.testSchemaDeleteClasses.assertResults(pizzaCreateStatus, @@ -122,8 +123,7 @@ public void testSchemaDeleteAllSchema() { WeaviateClass chickenSoup = SchemaTestSuite.testSchemaDeleteAllSchema.chickenSoup; // when Result pizzaCreateStatus = client.schema().classCreator().withClass(pizza).run(); - Result chickenSoupCreateStatus = - client.schema().classCreator().withClass(chickenSoup).run(); + Result chickenSoupCreateStatus = client.schema().classCreator().withClass(chickenSoup).run(); Result schemaAfterCreate = client.schema().getter().run(); Result deleteAllStatus = client.schema().allDeleter().run(); Result schemaAfterDelete = client.schema().getter().run(); @@ -140,8 +140,7 @@ public void testSchemaCreateClassesAddProperties() { Property newProperty = SchemaTestSuite.testSchemaCreateClassesAddProperties.newProperty; // when Result pizzaCreateStatus = client.schema().classCreator().withClass(pizza).run(); - Result chickenSoupCreateStatus = - client.schema().classCreator().withClass(chickenSoup).run(); + Result chickenSoupCreateStatus = client.schema().classCreator().withClass(chickenSoup).run(); Result pizzaPropertyCreateStatus = client.schema().propertyCreator() .withProperty(newProperty).withClassName(pizza.getClassName()).run(); Result chickenSoupPropertyCreateStatus = client.schema().propertyCreator() @@ -156,56 +155,39 @@ public void testSchemaCreateClassesAddProperties() { } @Test - public void testSchemaCreateClassExplicitVectorizerWithProperties() { - // given - Map text2vecContextionary = new HashMap<>(); - text2vecContextionary.put("vectorizeClassName", false); - Map moduleConfig = new HashMap<>(); - moduleConfig.put("text2vec-contextionary", text2vecContextionary); - - WeaviateClass clazz = WeaviateClass.builder().className("Article") - .description("A written text, for example a news article or blog post") - .vectorIndexType("hnsw").vectorizer("text2vec-contextionary").moduleConfig(moduleConfig) - .properties(new ArrayList() { - { - add(Property.builder().dataType(new ArrayList() { - { - add(DataType.TEXT); - } - }).description("Title of the article").name("title").tokenization(Tokenization.FIELD) - .build()); - add(Property.builder().dataType(new ArrayList() { - { - add(DataType.TEXT); - } - }).description("The content of the article").name("content") - .tokenization(Tokenization.WORD).build()); - } - }).build(); - // when - Result createStatus = client.schema().classCreator().withClass(clazz).run(); - Result schemaAfterCreate = client.schema().getter().run(); - Result deleteStatus = client.schema().allDeleter().run(); - Result schemaAfterDelete = client.schema().getter().run(); - - // then - assertResultTrue(createStatus); - assertClassesSize(1, schemaAfterCreate); - - WeaviateClass resultArticleClass = schemaAfterCreate.getResult().getClasses().get(0); - assertClassEquals(clazz.getClassName(), clazz.getDescription(), resultArticleClass); - - assertThat(resultArticleClass.getModuleConfig()).asInstanceOf(MAP) - .containsOnlyKeys("text2vec-contextionary").extracting(m -> m.get("text2vec-contextionary")) - .asInstanceOf(MAP).containsOnlyKeys("vectorizeClassName") - .extracting(m -> m.get("vectorizeClassName")).isEqualTo(false); - - assertPropertiesSize(2, resultArticleClass); - assertPropertyEquals("title", "field", resultArticleClass.getProperties().get(0)); - assertPropertyEquals("content", "word", resultArticleClass.getProperties().get(1)); + public void testSchemaAddVectors() { + // Arrange + VectorConfig vector = VectorConfig.builder() + .vectorIndexType("hnsw") + .vectorizer(Collections.singletonMap("none", Collections.emptyMap())) + .vectorIndexConfig(VectorIndexConfig.builder().build()) + .build(); + String className = "Pizza_testSchemaAddVectors"; + client.schema().classCreator() + .withClass(WeaviateClass.builder() + .className(className) + .properties(Collections.singletonList( + Property.builder() + .name("title").dataType(Collections.singletonList(DataType.TEXT)) + .build())) + .vectorConfig(Collections.singletonMap("default", vector)) + .build()) + .run(); + + // Act + Result add = client.schema().vectorAdder() + .withClass(className) + .withVector("vector-a", vector) + .withVector("vector-b", vector) + .run(); + assertNull("error adding new vectors", add.getError()); + + Result result = client.schema().classGetter().withClassName(className).run(); + WeaviateClass pizza = result.getResult(); + assertThat(pizza.getVectorConfig()) + .as("has all 3 vectors") + .containsKeys("default", "vector-a", "vector-b"); - assertResultTrue(deleteStatus); - assertClassesSize(0, schemaAfterDelete); } @Test @@ -323,12 +305,11 @@ public void testSchemaCreateClassWithInvalidTokenizationProperty() { .description("A delicious religion like food and arguably the best export of Italy.") .build(); - Property notExistingTokenization = - Property.builder().dataType(Collections.singletonList(DataType.TEXT)) - .description("someString").name("someString").tokenization("not-existing").build(); - Property notSupportedTokenizationForInt = - Property.builder().dataType(Collections.singletonList(DataType.INT)).description("someInt") - .name("someInt").tokenization(Tokenization.WORD).build(); + Property notExistingTokenization = Property.builder().dataType(Collections.singletonList(DataType.TEXT)) + .description("someString").name("someString").tokenization("not-existing").build(); + Property notSupportedTokenizationForInt = Property.builder().dataType(Collections.singletonList(DataType.INT)) + .description("someInt") + .name("someInt").tokenization(Tokenization.WORD).build(); // when Result createStatus = client.schema().classCreator().withClass(pizza).run(); Result notExistingTokenizationCreateStatus = client.schema().propertyCreator() @@ -351,8 +332,7 @@ public void testCreateClassWithBM25Config() { // given BM25Config bm25Config = BM25Config.builder().b(0.777f).k1(1.777f).build(); - InvertedIndexConfig invertedIndexConfig = - InvertedIndexConfig.builder().bm25(bm25Config).build(); + InvertedIndexConfig invertedIndexConfig = InvertedIndexConfig.builder().bm25(bm25Config).build(); WeaviateClass clazz = WeaviateClass.builder().className("Band") .description("Band that plays and produces music").vectorIndexType("hnsw") @@ -360,8 +340,7 @@ public void testCreateClassWithBM25Config() { // when Result createStatus = client.schema().classCreator().withClass(clazz).run(); - Result bandClass = - client.schema().classGetter().withClassName(clazz.getClassName()).run(); + Result bandClass = client.schema().classGetter().withClassName(clazz.getClassName()).run(); // then assertNotNull(createStatus); @@ -379,8 +358,7 @@ public void testCreateClassWithBM25Config() { @Test public void testCreateClassWithInvertedIndexContainingIndexNullState() { // given - InvertedIndexConfig invertedIndexConfig = - InvertedIndexConfig.builder().indexNullState(true).build(); + InvertedIndexConfig invertedIndexConfig = InvertedIndexConfig.builder().indexNullState(true).build(); WeaviateClass clazz = WeaviateClass.builder().className("Band") .description("Band that plays and produces music").vectorIndexType("hnsw") @@ -388,8 +366,7 @@ public void testCreateClassWithInvertedIndexContainingIndexNullState() { // when Result createStatus = client.schema().classCreator().withClass(clazz).run(); - Result bandClass = - client.schema().classGetter().withClassName(clazz.getClassName()).run(); + Result bandClass = client.schema().classGetter().withClassName(clazz.getClassName()).run(); // then assertNotNull(createStatus); @@ -403,8 +380,7 @@ public void testCreateClassWithInvertedIndexContainingIndexNullState() { @Test public void testCreateClassWithInvertedIndexContainingIndexPropertyLength() { // given - InvertedIndexConfig invertedIndexConfig = - InvertedIndexConfig.builder().indexPropertyLength(true).build(); + InvertedIndexConfig invertedIndexConfig = InvertedIndexConfig.builder().indexPropertyLength(true).build(); WeaviateClass clazz = WeaviateClass.builder().className("Band") .description("Band that plays and produces music").vectorIndexType("hnsw") @@ -412,8 +388,7 @@ public void testCreateClassWithInvertedIndexContainingIndexPropertyLength() { // when Result createStatus = client.schema().classCreator().withClass(clazz).run(); - Result bandClass = - client.schema().classGetter().withClassName(clazz.getClassName()).run(); + Result bandClass = client.schema().classGetter().withClassName(clazz.getClassName()).run(); // then assertNotNull(createStatus); @@ -428,10 +403,9 @@ public void testCreateClassWithInvertedIndexContainingIndexPropertyLength() { public void testCreateClassWithStopwordsConfig() { // given StopwordConfig stopwordConfig = StopwordConfig.builder().preset("en") - .additions(new String[] {"star", "nebula"}).removals(new String[] {"a", "the"}).build(); + .additions(new String[] { "star", "nebula" }).removals(new String[] { "a", "the" }).build(); - InvertedIndexConfig invertedIndexConfig = - InvertedIndexConfig.builder().stopwords(stopwordConfig).build(); + InvertedIndexConfig invertedIndexConfig = InvertedIndexConfig.builder().stopwords(stopwordConfig).build(); WeaviateClass clazz = WeaviateClass.builder().className("Band") .description("Band that plays and produces music").vectorIndexType("hnsw") @@ -439,8 +413,7 @@ public void testCreateClassWithStopwordsConfig() { // when Result createStatus = client.schema().classCreator().withClass(clazz).run(); - Result bandClass = - client.schema().classGetter().withClassName(clazz.getClassName()).run(); + Result bandClass = client.schema().classGetter().withClassName(clazz.getClassName()).run(); // then assertNotNull(createStatus); @@ -463,10 +436,10 @@ public void testCreateClassWithBM25ConfigAndWithStopwordsConfig() { BM25Config bm25Config = BM25Config.builder().b(0.777f).k1(1.777f).build(); StopwordConfig stopwordConfig = StopwordConfig.builder().preset("en") - .additions(new String[] {"star", "nebula"}).removals(new String[] {"a", "the"}).build(); + .additions(new String[] { "star", "nebula" }).removals(new String[] { "a", "the" }).build(); - InvertedIndexConfig invertedIndexConfig = - InvertedIndexConfig.builder().bm25(bm25Config).stopwords(stopwordConfig).build(); + InvertedIndexConfig invertedIndexConfig = InvertedIndexConfig.builder().bm25(bm25Config).stopwords(stopwordConfig) + .build(); WeaviateClass clazz = WeaviateClass.builder().className("Band") .description("Band that plays and produces music").vectorIndexType("hnsw") @@ -474,8 +447,7 @@ public void testCreateClassWithBM25ConfigAndWithStopwordsConfig() { // when Result createStatus = client.schema().classCreator().withClass(clazz).run(); - Result bandClass = - client.schema().classGetter().withClassName(clazz.getClassName()).run(); + Result bandClass = client.schema().classGetter().withClassName(clazz.getClassName()).run(); // then assertNotNull(createStatus); @@ -502,7 +474,7 @@ public void testCreateClassWithInvertedIndexConfigAndVectorIndexConfigAndShardCo // given BM25Config bm25Config = BM25Config.builder().b(0.777f).k1(1.777f).build(); StopwordConfig stopwordConfig = StopwordConfig.builder().preset("en") - .additions(new String[] {"star", "nebula"}).removals(new String[] {"a", "the"}).build(); + .additions(new String[] { "star", "nebula" }).removals(new String[] { "a", "the" }).build(); Integer cleanupIntervalSeconds = 300; // vector index config Integer efConstruction = 128; @@ -535,22 +507,21 @@ public void testCreateClassWithInvertedIndexConfigAndVectorIndexConfigAndShardCo InvertedIndexConfig invertedIndexConfig = InvertedIndexConfig.builder().bm25(bm25Config) .stopwords(stopwordConfig).cleanupIntervalSeconds(cleanupIntervalSeconds).build(); - VectorIndexConfig vectorIndexConfig = - VectorIndexConfig.builder().cleanupIntervalSeconds(cleanupIntervalSeconds) - .efConstruction(efConstruction).maxConnections(maxConnections) - .vectorCacheMaxObjects(vectorCacheMaxObjects).ef(ef).skip(skip) - .dynamicEfFactor(dynamicEfFactor).dynamicEfMax(dynamicEfMax).dynamicEfMin(dynamicEfMin) - .flatSearchCutoff(flatSearchCutoff).distance(distance).pq( - PQConfig.builder().enabled(enabled).bitCompression(bitCompression) - .segments(segments).centroids(centroids).encoder(PQConfig.Encoder.builder() - .type(encoderType).distribution(encoderDistribution).build()) - .build()) - .build(); - - ShardingConfig shardingConfig = - ShardingConfig.builder().actualCount(actualCount).actualVirtualCount(actualVirtualCount) - .desiredCount(desiredCount).desiredVirtualCount(desiredVirtualCount).function(function) - .key(key).strategy(strategy).virtualPerPhysical(virtualPerPhysical).build(); + VectorIndexConfig vectorIndexConfig = VectorIndexConfig.builder().cleanupIntervalSeconds(cleanupIntervalSeconds) + .efConstruction(efConstruction).maxConnections(maxConnections) + .vectorCacheMaxObjects(vectorCacheMaxObjects).ef(ef).skip(skip) + .dynamicEfFactor(dynamicEfFactor).dynamicEfMax(dynamicEfMax).dynamicEfMin(dynamicEfMin) + .flatSearchCutoff(flatSearchCutoff).distance(distance).pq( + PQConfig.builder().enabled(enabled).bitCompression(bitCompression) + .segments(segments).centroids(centroids).encoder(PQConfig.Encoder.builder() + .type(encoderType).distribution(encoderDistribution).build()) + .build()) + .build(); + + ShardingConfig shardingConfig = ShardingConfig.builder().actualCount(actualCount) + .actualVirtualCount(actualVirtualCount) + .desiredCount(desiredCount).desiredVirtualCount(desiredVirtualCount).function(function) + .key(key).strategy(strategy).virtualPerPhysical(virtualPerPhysical).build(); WeaviateClass clazz = WeaviateClass.builder().className("Band") .description("Band that plays and produces music").vectorIndexType("hnsw") @@ -559,8 +530,7 @@ public void testCreateClassWithInvertedIndexConfigAndVectorIndexConfigAndShardCo // when Result createStatus = client.schema().classCreator().withClass(clazz).run(); - Result bandClass = - client.schema().classGetter().withClassName(clazz.getClassName()).run(); + Result bandClass = client.schema().classGetter().withClassName(clazz.getClassName()).run(); // then assertNotNull(createStatus); @@ -613,15 +583,12 @@ public void testCreateClassWithInvertedIndexConfigAndVectorIndexConfigAndShardCo @Test public void testSchemaGetBandClass() { // given - WeaviateClass clazz = - WeaviateClass.builder().className("Band").description("Band that plays and produces music") - .vectorIndexType("hnsw").vectorizer("text2vec-contextionary").build(); + WeaviateClass clazz = WeaviateClass.builder().className("Band").description("Band that plays and produces music") + .vectorIndexType("hnsw").vectorizer("text2vec-contextionary").build(); // when Result createStatus = client.schema().classCreator().withClass(clazz).run(); - Result bandClass = - client.schema().classGetter().withClassName(clazz.getClassName()).run(); - Result nonExistentClass = - client.schema().classGetter().withClassName("nonExistentClass").run(); + Result bandClass = client.schema().classGetter().withClassName(clazz.getClassName()).run(); + Result nonExistentClass = client.schema().classGetter().withClassName("nonExistentClass").run(); // then assertNotNull(createStatus); assertTrue(createStatus.getResult()); @@ -640,23 +607,19 @@ public void testSchemaGetBandClass() { @Test public void testSchemaGetShards() { // given - WeaviateClass clazz = - WeaviateClass.builder().className("Band").description("Band that plays and produces music") - .vectorIndexType("hnsw").vectorizer("text2vec-contextionary").build(); + WeaviateClass clazz = WeaviateClass.builder().className("Band").description("Band that plays and produces music") + .vectorIndexType("hnsw").vectorizer("text2vec-contextionary").build(); // when Result createStatus = client.schema().classCreator().withClass(clazz).run(); - Result bandClassExists = - client.schema().exists().withClassName(clazz.getClassName()).run(); - Result nonExistentClassExists = - client.schema().exists().withClassName("nonExistentClass").run(); + Result bandClassExists = client.schema().exists().withClassName(clazz.getClassName()).run(); + Result nonExistentClassExists = client.schema().exists().withClassName("nonExistentClass").run(); // then assertResultTrue(createStatus); assertResultTrue(bandClassExists); assertNotNull(nonExistentClassExists); assertFalse(nonExistentClassExists.getResult()); assertNull(nonExistentClassExists.getError()); - Result shards = - client.schema().shardsGetter().withClassName(clazz.getClassName()).run(); + Result shards = client.schema().shardsGetter().withClassName(clazz.getClassName()).run(); assertNotNull(shards); assertNotNull(shards.getResult()); assertEquals(1, shards.getResult().length); @@ -741,8 +704,7 @@ public void testSchemaUpdateShards() { public void testSchemaUpdateShardsException() { // when Result res = client.schema().shardsUpdater().run(); - Result res2 = - client.schema().shardsUpdater().withStatus(ShardStatuses.READY).run(); + Result res2 = client.schema().shardsUpdater().withStatus(ShardStatuses.READY).run(); Result res3 = client.schema().shardsUpdater().withClassName("class").run(); // then assertResultError("className, status cannot be empty", res); @@ -1058,8 +1020,8 @@ public void shouldBatchObjectsWithNestedProperties_EntireSchema() { utils.assertThatSchemaPropertiesHaveDataTypes(expectedProps, schemaClass); // schema did not change after adding objects - ObjectGetResponse[] objects = - utils.batchObjects(client, utils.nestedObject1(className), utils.nestedObject2(className)); + ObjectGetResponse[] objects = utils.batchObjects(client, utils.nestedObject1(className), + utils.nestedObject2(className)); utils.assertThatObjectsAreSimilar(utils.expectedNestedObject1(className), objects[0]); utils.assertThatObjectsAreSimilar(utils.expectedNestedObject2(className), objects[1]); schemaClass = utils.getClass(client, className); @@ -1102,8 +1064,8 @@ public void shouldBatchObjectsWithNestedProperties_PartialSchema1() { utils.assertThatSchemaPropertiesHaveDataTypes(expectedPropsStep1, schemaClass); // schema changed after adding objects - ObjectGetResponse[] objects = - utils.batchObjects(client, utils.nestedObject1(className), utils.nestedObject2(className)); + ObjectGetResponse[] objects = utils.batchObjects(client, utils.nestedObject1(className), + utils.nestedObject2(className)); utils.assertThatObjectsAreSimilar(utils.expectedNestedObject1(className), objects[0]); utils.assertThatObjectsAreSimilar(utils.expectedNestedObject2(className), objects[1]); schemaClass = utils.getClass(client, className); @@ -1146,8 +1108,8 @@ public void shouldBatchObjectsWithNestedProperties_PartialSchema2() { utils.assertThatSchemaPropertiesHaveDataTypes(expectedPropsStep1, schemaClass); // schema changed after adding objects - ObjectGetResponse[] objects = - utils.batchObjects(client, utils.nestedObject1(className), utils.nestedObject2(className)); + ObjectGetResponse[] objects = utils.batchObjects(client, utils.nestedObject1(className), + utils.nestedObject2(className)); utils.assertThatObjectsAreSimilar(utils.expectedNestedObject1(className), objects[0]); utils.assertThatObjectsAreSimilar(utils.expectedNestedObject2(className), objects[1]); schemaClass = utils.getClass(client, className); @@ -1173,8 +1135,8 @@ public void shouldBatchObjectsWithNestedProperties_NoSchema1() { }; // schema created after adding objects - ObjectGetResponse[] objects = - utils.batchObjects(client, utils.nestedObject1(className), utils.nestedObject2(className)); + ObjectGetResponse[] objects = utils.batchObjects(client, utils.nestedObject1(className), + utils.nestedObject2(className)); utils.assertThatObjectsAreSimilar(utils.expectedNestedObject1(className), objects[0]); utils.assertThatObjectsAreSimilar(utils.expectedNestedObject2(className), objects[1]); schemaClass = utils.getClass(client, className); @@ -1200,8 +1162,8 @@ public void shouldBatchObjectsWithNestedProperties_NoSchema2() { }; // schema created after adding objects - ObjectGetResponse[] objects = - utils.batchObjects(client, utils.nestedObject2(className), utils.nestedObject1(className)); + ObjectGetResponse[] objects = utils.batchObjects(client, utils.nestedObject2(className), + utils.nestedObject1(className)); utils.assertThatObjectsAreSimilar(utils.expectedNestedObject2(className), objects[0]); utils.assertThatObjectsAreSimilar(utils.expectedNestedObject1(className), objects[1]); schemaClass = utils.getClass(client, className); @@ -1222,14 +1184,12 @@ public void shouldBatchObjectsWithNestedProperties_FromFileNestedObject() throws props.put("name", "nested object from file"); props.put("objectProperty", nestedOneObject); - WeaviateObject weaviateObject = - WeaviateObject.builder().className(className).id(id).properties(props).build(); + WeaviateObject weaviateObject = WeaviateObject.builder().className(className).id(id).properties(props).build(); // then ObjectGetResponse[] objects = utils.batchObjects(client, weaviateObject); assertThat(objects).isNotEmpty(); - Result> result = - client.data().objectsGetter().withID(id).withClassName(className).run(); + Result> result = client.data().objectsGetter().withID(id).withClassName(className).run(); assertThat(result).isNotNull().returns(false, Result::hasErrors).extracting(Result::getResult) .isNotNull().extracting(objs -> objs.get(0)).isNotNull().satisfies(obj -> { assertThat(obj.getId()).isEqualTo(id); @@ -1252,14 +1212,12 @@ public void shouldBatchObjectsWithNestedProperties_FromFileNestedArrayObject() t props.put("name", "nested object from file"); props.put("objectArrayProperty", nestedArrayObject); - WeaviateObject weaviateObject = - WeaviateObject.builder().className(className).id(id).properties(props).build(); + WeaviateObject weaviateObject = WeaviateObject.builder().className(className).id(id).properties(props).build(); // then ObjectGetResponse[] objects = utils.batchObjects(client, weaviateObject); assertThat(objects).isNotEmpty(); - Result> result = - client.data().objectsGetter().withID(id).withClassName(className).run(); + Result> result = client.data().objectsGetter().withID(id).withClassName(className).run(); assertThat(result).isNotNull().returns(false, Result::hasErrors).extracting(Result::getResult) .isNotNull().extracting(objs -> objs.get(0)).isNotNull().satisfies(obj -> { assertThat(obj.getId()).isEqualTo(id); @@ -1275,17 +1233,15 @@ public void shouldUpdateClass() { Property.builder().name("question").dataType(Arrays.asList(DataType.TEXT)).build(), Property.builder().name("answer").dataType(Arrays.asList(DataType.TEXT)).build()); - WeaviateClass jeopardyClass = - WeaviateClass.builder().className(className).description("A Jeopardy! question") - .vectorizer("text2vec-contextionary").properties(properties).build(); + WeaviateClass jeopardyClass = WeaviateClass.builder().className(className).description("A Jeopardy! question") + .vectorizer("text2vec-contextionary").properties(properties).build(); Result createResult = client.schema().classCreator().withClass(jeopardyClass).run(); assertThat(createResult).isNotNull().withFailMessage(() -> createResult.getError().toString()) .returns(false, Result::hasErrors).withFailMessage(null).returns(true, Result::getResult); - Result createdClassResult = - client.schema().classGetter().withClassName(className).run(); + Result createdClassResult = client.schema().classGetter().withClassName(className).run(); assertThat(createdClassResult).isNotNull() .withFailMessage(() -> createdClassResult.getError().toString()) @@ -1308,8 +1264,7 @@ public void shouldUpdateClass() { assertThat(updateResult).isNotNull().withFailMessage(() -> updateResult.getError().toString()) .returns(false, Result::hasErrors).withFailMessage(null).returns(true, Result::getResult); - Result updatedClassResult = - client.schema().classGetter().withClassName(className).run(); + Result updatedClassResult = client.schema().classGetter().withClassName(className).run(); assertThat(updatedClassResult).isNotNull() .withFailMessage(() -> updatedClassResult.getError().toString()) @@ -1349,22 +1304,21 @@ public void shouldCreateClassWithVectorAndReplicationConfig() { Boolean asyncEnabled = true; Integer replicationFactor = 1; - VectorIndexConfig vectorIndexConfig = - VectorIndexConfig.builder().cleanupIntervalSeconds(cleanupIntervalSeconds) - .efConstruction(efConstruction).maxConnections(maxConnections) - .vectorCacheMaxObjects(vectorCacheMaxObjects).ef(ef).skip(skip) - .filterStrategy(VectorIndexConfig.FilterStrategy.SWEEPING) - .dynamicEfFactor(dynamicEfFactor).dynamicEfMax(dynamicEfMax).dynamicEfMin(dynamicEfMin) - .flatSearchCutoff(flatSearchCutoff).distance(distance).pq( - PQConfig.builder().enabled(enabled).bitCompression(bitCompression) - .segments(segments).centroids(centroids).encoder(PQConfig.Encoder.builder() - .type(encoderType).distribution(encoderDistribution).build()) - .build()) - .build(); - - ReplicationConfig replicationConfig = - ReplicationConfig.builder().factor(replicationFactor).asyncEnabled(asyncEnabled) - .deletionStrategy(ReplicationConfig.DeletionStrategy.NO_AUTOMATED_RESOLUTION).build(); + VectorIndexConfig vectorIndexConfig = VectorIndexConfig.builder().cleanupIntervalSeconds(cleanupIntervalSeconds) + .efConstruction(efConstruction).maxConnections(maxConnections) + .vectorCacheMaxObjects(vectorCacheMaxObjects).ef(ef).skip(skip) + .filterStrategy(VectorIndexConfig.FilterStrategy.SWEEPING) + .dynamicEfFactor(dynamicEfFactor).dynamicEfMax(dynamicEfMax).dynamicEfMin(dynamicEfMin) + .flatSearchCutoff(flatSearchCutoff).distance(distance).pq( + PQConfig.builder().enabled(enabled).bitCompression(bitCompression) + .segments(segments).centroids(centroids).encoder(PQConfig.Encoder.builder() + .type(encoderType).distribution(encoderDistribution).build()) + .build()) + .build(); + + ReplicationConfig replicationConfig = ReplicationConfig.builder().factor(replicationFactor) + .asyncEnabled(asyncEnabled) + .deletionStrategy(ReplicationConfig.DeletionStrategy.NO_AUTOMATED_RESOLUTION).build(); Map contextionaryVectorizerSettings = new HashMap<>(); contextionaryVectorizerSettings.put("vectorizeClassName", true); @@ -1376,17 +1330,15 @@ public void shouldCreateClassWithVectorAndReplicationConfig() { WeaviateClass.VectorConfig.builder().vectorIndexConfig(vectorIndexConfig) .vectorIndexType("hnsw").vectorizer(contextionaryVectorizer).build()); - WeaviateClass clazz = - WeaviateClass.builder().className("Band").description("Band that plays and produces music") - .vectorConfig(vectorConfig).replicationConfig(replicationConfig).build(); + WeaviateClass clazz = WeaviateClass.builder().className("Band").description("Band that plays and produces music") + .vectorConfig(vectorConfig).replicationConfig(replicationConfig).build(); Result createStatus = client.schema().classCreator().withClass(clazz).run(); assertThat(createStatus).isNotNull().returns(false, Result::hasErrors).returns(true, Result::getResult); - Result bandClass = - client.schema().classGetter().withClassName(clazz.getClassName()).run(); + Result bandClass = client.schema().classGetter().withClassName(clazz.getClassName()).run(); assertThat(bandClass).isNotNull().returns(false, Result::hasErrors) .extracting(Result::getResult).isNotNull().extracting(WeaviateClass::getVectorConfig) From 628ed1d97dd68e3ac3bc117b147eb91a606b9479 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Mon, 2 Jun 2025 17:24:01 +0200 Subject: [PATCH 3/6] ci: update expected git hash --- .../java/io/weaviate/integration/client/WeaviateVersion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/io/weaviate/integration/client/WeaviateVersion.java b/src/test/java/io/weaviate/integration/client/WeaviateVersion.java index 358cd29d5..95d0db20f 100644 --- a/src/test/java/io/weaviate/integration/client/WeaviateVersion.java +++ b/src/test/java/io/weaviate/integration/client/WeaviateVersion.java @@ -8,7 +8,7 @@ public class WeaviateVersion { // to be set according to weaviate docker image public static final String EXPECTED_WEAVIATE_VERSION = "1.31.0"; // to be set according to weaviate docker image - public static final String EXPECTED_WEAVIATE_GIT_HASH = "5ff7495"; + public static final String EXPECTED_WEAVIATE_GIT_HASH = "79499d6"; private WeaviateVersion() { } From 3750fa97ed15b949c7a23cb9b06f116d7f575950 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Mon, 2 Jun 2025 23:24:02 +0200 Subject: [PATCH 4/6] refactor: rename builder methods to withVectorConfig --- .../io/weaviate/client/v1/async/schema/api/VectorAdder.java | 4 ++-- .../java/io/weaviate/client/v1/schema/api/VectorAdder.java | 4 ++-- .../integration/client/async/schema/ClientSchemaTest.java | 4 ++-- .../weaviate/integration/client/schema/ClientSchemaTest.java | 5 ++--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java b/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java index 3fa95177d..6b8e4ac03 100644 --- a/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java +++ b/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java @@ -44,7 +44,7 @@ public VectorAdder withClass(String className) { * Add a named vectors. This method can be chained to add multiple named vectors * without using a {@link Map}. */ - public VectorAdder withVector(String name, VectorConfig vector) { + public VectorAdder withVectorConfig(String name, VectorConfig vector) { this.addedVectors.put(name, vector); return this; } @@ -53,7 +53,7 @@ public VectorAdder withVector(String name, VectorConfig vector) { * Add all vectors from the map. This will overwrite any vectors added * previously. */ - public VectorAdder withVector(Map vectors) { + public VectorAdder withVectorConfig(Map vectors) { this.addedVectors = Collections.unmodifiableMap(vectors); return this; } diff --git a/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java b/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java index 5fcc71bbf..4e36b0f4d 100644 --- a/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java +++ b/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java @@ -34,7 +34,7 @@ public VectorAdder withClass(String className) { * Add a named vectors. This method can be chained to add multiple named vectors * without using a {@link Map}. */ - public VectorAdder withVector(String name, VectorConfig vector) { + public VectorAdder withVectorConfig(String name, VectorConfig vector) { this.addedVectors.put(name, vector); return this; } @@ -43,7 +43,7 @@ public VectorAdder withVector(String name, VectorConfig vector) { * Add all vectors from the map. This will overwrite any vectors added * previously. */ - public VectorAdder withVector(Map vectors) { + public VectorAdder withVectorConfig(Map vectors) { this.addedVectors = Collections.unmodifiableMap(vectors); return this; } diff --git a/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java b/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java index cf72439b1..72709452b 100644 --- a/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java +++ b/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java @@ -300,8 +300,8 @@ public void cancelled() { }; Result add = client.schema().vectorAdder() .withClass(className) - .withVector("vector-a", vector) - .withVector("vector-b", vector) + .withVectorConfig("vector-a", v + .run(callback).get(); assertNull("error adding new vectors", add.getError()); diff --git a/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java b/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java index 611a3c239..aad695e6e 100644 --- a/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java +++ b/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java @@ -177,8 +177,8 @@ public void testSchemaAddVectors() { // Act Result add = client.schema().vectorAdder() .withClass(className) - .withVector("vector-a", vector) - .withVector("vector-b", vector) + .withVectorConfig("vector-a", vector) + .withVectorConfig("vector-b", vector) .run(); assertNull("error adding new vectors", add.getError()); @@ -187,7 +187,6 @@ public void testSchemaAddVectors() { assertThat(pizza.getVectorConfig()) .as("has all 3 vectors") .containsKeys("default", "vector-a", "vector-b"); - } @Test From 784482019f4ffae26e1a4b2f1e3439f6f69a4ec6 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Tue, 3 Jun 2025 00:01:13 +0200 Subject: [PATCH 5/6] chore: fix unintended file change --- .../integration/client/async/schema/ClientSchemaTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java b/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java index 72709452b..4f0a88373 100644 --- a/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java +++ b/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java @@ -300,8 +300,8 @@ public void cancelled() { }; Result add = client.schema().vectorAdder() .withClass(className) - .withVectorConfig("vector-a", v - + .withVectorConfig("vector-a", vector) + .withVectorConfig("vector-b", vector) .run(callback).get(); assertNull("error adding new vectors", add.getError()); From 5c1b80f8af0dc9158b3544542bb6bc154c3772f1 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Mon, 16 Jun 2025 13:01:29 +0200 Subject: [PATCH 6/6] refactor: rename method to follow naming conventions --- .../io/weaviate/client/v1/async/schema/api/VectorAdder.java | 2 +- src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java | 2 +- .../integration/client/async/schema/ClientSchemaTest.java | 2 +- .../io/weaviate/integration/client/schema/ClientSchemaTest.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java b/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java index 6b8e4ac03..40664c795 100644 --- a/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java +++ b/src/main/java/io/weaviate/client/v1/async/schema/api/VectorAdder.java @@ -35,7 +35,7 @@ public VectorAdder(CloseableHttpAsyncClient client, Config config, AccessTokenPr this.getter = new ClassGetter(client, config, tokenProvider); } - public VectorAdder withClass(String className) { + public VectorAdder withClassName(String className) { this.className = className; return this; } diff --git a/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java b/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java index 4e36b0f4d..85968c905 100644 --- a/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java +++ b/src/main/java/io/weaviate/client/v1/schema/api/VectorAdder.java @@ -25,7 +25,7 @@ public VectorAdder(HttpClient httpClient, Config config) { this.getter = new ClassGetter(httpClient, config); } - public VectorAdder withClass(String className) { + public VectorAdder withClassName(String className) { this.className = className; return this; } diff --git a/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java b/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java index 4f0a88373..96cbb9613 100644 --- a/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java +++ b/src/test/java/io/weaviate/integration/client/async/schema/ClientSchemaTest.java @@ -299,7 +299,7 @@ public void cancelled() { } }; Result add = client.schema().vectorAdder() - .withClass(className) + .withClassName(className) .withVectorConfig("vector-a", vector) .withVectorConfig("vector-b", vector) .run(callback).get(); diff --git a/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java b/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java index aad695e6e..27fb05f45 100644 --- a/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java +++ b/src/test/java/io/weaviate/integration/client/schema/ClientSchemaTest.java @@ -176,7 +176,7 @@ public void testSchemaAddVectors() { // Act Result add = client.schema().vectorAdder() - .withClass(className) + .withClassName(className) .withVectorConfig("vector-a", vector) .withVectorConfig("vector-b", vector) .run();