diff --git a/src/it/java/io/weaviate/integration/DataITest.java b/src/it/java/io/weaviate/integration/DataITest.java index d8ae6401c..349ce5253 100644 --- a/src/it/java/io/weaviate/integration/DataITest.java +++ b/src/it/java/io/weaviate/integration/DataITest.java @@ -9,6 +9,7 @@ import org.assertj.core.api.Assertions; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import io.weaviate.ConcurrentTest; @@ -20,15 +21,17 @@ import io.weaviate.client6.v1.api.collections.ReferenceProperty; import io.weaviate.client6.v1.api.collections.VectorConfig; import io.weaviate.client6.v1.api.collections.Vectors; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.data.BatchReference; import io.weaviate.client6.v1.api.collections.data.DeleteManyResponse; import io.weaviate.client6.v1.api.collections.data.Reference; +import io.weaviate.client6.v1.api.collections.data.WriteWeaviateObject; import io.weaviate.client6.v1.api.collections.query.Filter; import io.weaviate.client6.v1.api.collections.query.Metadata; import io.weaviate.client6.v1.api.collections.query.Metadata.MetadataField; import io.weaviate.client6.v1.api.collections.query.QueryMetadata; import io.weaviate.client6.v1.api.collections.query.QueryReference; +import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject; +import io.weaviate.client6.v1.api.collections.tenants.Tenant; import io.weaviate.containers.Container; public class DataITest extends ConcurrentTest { @@ -86,6 +89,7 @@ public void testCreateGetDelete() throws IOException { .as("object not exists after deletion").isFalse(); deleted = artists.data.deleteById(id); + // TODO: Change to isFalse() after fixed in Weaviate server Assertions.assertThat(deleted) .as("object wasn't deleted").isTrue(); @@ -106,11 +110,11 @@ public void testBlobData() throws IOException { "breed", "ragdoll", "img", ragdollPng)); - var got = cats.query.fetchObjectById(ragdoll.metadata().uuid(), + var got = cats.query.fetchObjectById(ragdoll.uuid(), cat -> cat.returnProperties("img")); Assertions.assertThat(got).get() - .extracting(WeaviateObject::properties, InstanceOfAssertFactories.MAP) + .extracting(ReadWeaviateObject::properties, InstanceOfAssertFactories.MAP) .extractingByKey("img").isEqualTo(ragdollPng); } @@ -147,59 +151,59 @@ public void testReferences_AddReplaceDelete() throws IOException { // Act: add reference persons.data.referenceAdd( - john.metadata().uuid(), + john.uuid(), "hasFriend", Reference.object(albie)); // Assert - var johnWithFriends = persons.query.fetchObjectById(john.metadata().uuid(), + var johnWithFriends = persons.query.fetchObjectById(john.uuid(), query -> query.returnReferences( QueryReference.single("hasFriend", friend -> friend.returnProperties("name")))); Assertions.assertThat(johnWithFriends).get() .as("friends after ADD") - .extracting(WeaviateObject::references).extracting("hasFriend") - .asInstanceOf(InstanceOfAssertFactories.list(WeaviateObject.class)) + .extracting(ReadWeaviateObject::references).extracting("hasFriend") + .asInstanceOf(InstanceOfAssertFactories.list(ReadWeaviateObject.class)) .hasSize(1) - .first().extracting(WeaviateObject::properties, InstanceOfAssertFactories.MAP) + .first().extracting(ReadWeaviateObject::properties, InstanceOfAssertFactories.MAP) .returns("albie", friend -> friend.get("name")); // Act: replace reference var barbara = persons.data.insert(Map.of("name", "barbara")); persons.data.referenceReplace( - john.metadata().uuid(), + john.uuid(), "hasFriend", Reference.object(barbara)); - johnWithFriends = persons.query.fetchObjectById(john.metadata().uuid(), + johnWithFriends = persons.query.fetchObjectById(john.uuid(), query -> query.returnReferences( QueryReference.single("hasFriend", friend -> friend.returnProperties("name")))); Assertions.assertThat(johnWithFriends).get() .as("friends after REPLACE") - .extracting(WeaviateObject::references).extracting("hasFriend") - .asInstanceOf(InstanceOfAssertFactories.list(WeaviateObject.class)) + .extracting(ReadWeaviateObject::references).extracting("hasFriend") + .asInstanceOf(InstanceOfAssertFactories.list(ReadWeaviateObject.class)) .hasSize(1) - .first().extracting(WeaviateObject::properties, InstanceOfAssertFactories.MAP) + .first().extracting(ReadWeaviateObject::properties, InstanceOfAssertFactories.MAP) .returns("barbara", friend -> friend.get("name")); // Act: delete reference persons.data.referenceDelete( - john.metadata().uuid(), + john.uuid(), "hasFriend", Reference.object(barbara)); // Assert - johnWithFriends = persons.query.fetchObjectById(john.metadata().uuid(), + johnWithFriends = persons.query.fetchObjectById(john.uuid(), query -> query.returnReferences( QueryReference.single("hasFriend"))); Assertions.assertThat(johnWithFriends).get() .as("friends after DELETE") - .extracting(WeaviateObject::references).extracting("hasFriend") - .asInstanceOf(InstanceOfAssertFactories.list(WeaviateObject.class)) + .extracting(ReadWeaviateObject::references).extracting("hasFriend") + .asInstanceOf(InstanceOfAssertFactories.list(ReadWeaviateObject.class)) .isEmpty(); } @@ -217,15 +221,15 @@ public void testReplace() throws IOException { var ivanhoe = books.data.insert(Map.of("title", "ivanhoe")); // Act - books.data.replace(ivanhoe.metadata().uuid(), + books.data.replace(ivanhoe.uuid(), replace -> replace.properties(Map.of("year", 1819))); // Assert - var replacedIvanhoe = books.query.fetchObjectById(ivanhoe.metadata().uuid()); + var replacedIvanhoe = books.query.fetchObjectById(ivanhoe.uuid()); Assertions.assertThat(replacedIvanhoe).get() .as("has ONLY year property") - .extracting(WeaviateObject::properties, InstanceOfAssertFactories.MAP) + .extracting(ReadWeaviateObject::properties, InstanceOfAssertFactories.MAP) .doesNotContain(Map.entry("title", "ivanhoe")) .contains(Map.entry("year", 1819L)); } @@ -258,7 +262,7 @@ public void testUpdate() throws IOException { var ivanhoe = books.data.insert(Map.of("title", "ivanhoe")); // Act - books.data.update(ivanhoe.metadata().uuid(), + books.data.update(ivanhoe.uuid(), update -> update .properties(Map.of("year", 1819)) .reference("writtenBy", Reference.objects(walter)) @@ -266,7 +270,7 @@ public void testUpdate() throws IOException { // Assert var updIvanhoe = books.query.fetchObjectById( - ivanhoe.metadata().uuid(), + ivanhoe.uuid(), query -> query .includeVector() .returnReferences(QueryReference.single("writtenBy"))); @@ -275,20 +279,20 @@ public void testUpdate() throws IOException { .satisfies(book -> { Assertions.assertThat(book) .as("has both year and title property") - .extracting(WeaviateObject::properties, InstanceOfAssertFactories.MAP) + .extracting(ReadWeaviateObject::properties, InstanceOfAssertFactories.MAP) .contains(Map.entry("title", "ivanhoe"), Map.entry("year", 1819L)); Assertions.assertThat(book) .as("has reference to Authors") - .extracting(WeaviateObject::references, InstanceOfAssertFactories.MAP) - .extractingByKey("writtenBy", InstanceOfAssertFactories.list(WeaviateObject.class)) + .extracting(ReadWeaviateObject::references, InstanceOfAssertFactories.MAP) + .extractingByKey("writtenBy", InstanceOfAssertFactories.list(ReadWeaviateObject.class)) .first() - .extracting(WeaviateObject::properties, InstanceOfAssertFactories.MAP) + .extracting(ReadWeaviateObject::properties, InstanceOfAssertFactories.MAP) .contains(Map.entry("name", "walter scott")); Assertions.assertThat(book) .as("has a vector") - .extracting(WeaviateObject::metadata) + .extracting(ReadWeaviateObject::metadata) .extracting(QueryMetadata::vectors) .returns(vector, Vectors::getDefaultSingle); }); @@ -305,8 +309,8 @@ public void testDeleteMany() throws IOException { var things = client.collections.use(nsThings); things.data.insert(Map.of("last_used", 1)); - var delete_1 = things.data.insert(Map.of("last_used", 5)).metadata().uuid(); - var delete_2 = things.data.insert(Map.of("last_used", 9)).metadata().uuid(); + var delete_1 = things.data.insert(Map.of("last_used", 5)).uuid(); + var delete_2 = things.data.insert(Map.of("last_used", 9)).uuid(); // Act (dry run) things.data.deleteMany( @@ -394,15 +398,16 @@ public void testReferenceAddMany() throws IOException { // Assert Assertions.assertThat(response.errors()).isEmpty(); - var goodburgAirports = cities.query.fetchObjectById(goodburg.metadata().uuid(), + var goodburgAirports = cities.query.fetchObjectById(goodburg.uuid(), city -> city.returnReferences( QueryReference.single("hasAirports"))); Assertions.assertThat(goodburgAirports).get() .as("Goodburg has 3 airports") - .extracting(WeaviateObject::references) - .extracting(references -> references.get("hasAirports"), InstanceOfAssertFactories.list(WeaviateObject.class)) - .extracting(WeaviateObject::uuid) + .extracting(ReadWeaviateObject::references) + .extracting(references -> references.get("hasAirports"), + InstanceOfAssertFactories.list(ReadWeaviateObject.class)) + .extracting(ReadWeaviateObject::uuid) .contains(alpha, bravo, charlie); } @@ -480,7 +485,7 @@ public void testDataTypes() throws IOException { // Assert Assertions.assertThat(got).get() - .extracting(WeaviateObject::properties) + .extracting(ReadWeaviateObject::properties) .asInstanceOf(InstanceOfAssertFactories.map(String.class, Object.class)) // Most of PhoneNumber fields are only present on read and are null on write. .usingRecursiveComparison() @@ -535,4 +540,23 @@ public void testNestedProperties_insertMany() throws IOException { // Assert Assertions.assertThat(result.errors()).isEmpty(); } + + @Ignore("Making Emails collection multi-tenant causes ReferencesITest::testNestedReferences to fail") + @Test + public void test_multiTenant() throws IOException { + // Arrange + var nsEmails = ns("Emails"); + var emails = client.collections.create(nsEmails, + c -> c.multiTenancy(mt -> mt.enabled(true))); + + var johndoe = "john-doe"; + emails.tenants.create(Tenant.active(johndoe)); + emails = emails.withTenant(johndoe); + + // Act + var inserted = emails.data.insert(Map.of("subject", "McDonald's Xmas Bonanza")); + + // Assert + Assertions.assertThat(inserted).returns(johndoe, WriteWeaviateObject::tenant); + } } diff --git a/src/it/java/io/weaviate/integration/ORMITest.java b/src/it/java/io/weaviate/integration/ORMITest.java index 6095d91b4..a5e0984ed 100644 --- a/src/it/java/io/weaviate/integration/ORMITest.java +++ b/src/it/java/io/weaviate/integration/ORMITest.java @@ -17,10 +17,10 @@ import io.weaviate.client6.v1.api.collections.CollectionConfig; import io.weaviate.client6.v1.api.collections.GeoCoordinates; import io.weaviate.client6.v1.api.collections.PhoneNumber; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.annotations.Collection; import io.weaviate.client6.v1.api.collections.annotations.Property; import io.weaviate.client6.v1.api.collections.data.InsertManyResponse.InsertObject; +import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject; import io.weaviate.client6.v1.api.collections.query.Filter; import io.weaviate.containers.Container; @@ -358,7 +358,7 @@ public void test_partialScan() throws IOException { // Assert Assertions.assertThat(got).get() - .extracting(WeaviateObject::properties) + .extracting(ReadWeaviateObject::properties) .returns("Dystopia", Song::title) .returns(null, Song::album) .returns(0, Song::year) diff --git a/src/it/java/io/weaviate/integration/PaginationITest.java b/src/it/java/io/weaviate/integration/PaginationITest.java index b4b02d291..b5e789e2b 100644 --- a/src/it/java/io/weaviate/integration/PaginationITest.java +++ b/src/it/java/io/weaviate/integration/PaginationITest.java @@ -18,10 +18,10 @@ import io.weaviate.client6.v1.api.WeaviateClient; import io.weaviate.client6.v1.api.WeaviateException; import io.weaviate.client6.v1.api.collections.Property; -import io.weaviate.client6.v1.api.collections.WeaviateMetadata; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.pagination.PaginationException; import io.weaviate.client6.v1.api.collections.query.Metadata; +import io.weaviate.client6.v1.api.collections.query.QueryMetadata; +import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject; import io.weaviate.containers.Container; public class PaginationITest extends ConcurrentTest { @@ -39,7 +39,7 @@ public void testIterateAll() throws IOException { var inserted = new ArrayList(); for (var i = 0; i < count; i++) { var object = things.data.insert(Collections.emptyMap()); - inserted.add(object.metadata().uuid()); + inserted.add(object.uuid()); } assumeTrue("all objects were inserted", inserted.size() == count); @@ -47,7 +47,7 @@ public void testIterateAll() throws IOException { // Act: stream var gotStream = allThings.stream() - .map(WeaviateObject::metadata).map(WeaviateMetadata::uuid).toList(); + .map(ReadWeaviateObject::metadata).map(QueryMetadata::uuid).toList(); // Assert Assertions.assertThat(gotStream) @@ -84,7 +84,7 @@ public void testResumePagination() throws IOException { var inserted = new ArrayList(); for (var i = 0; i < count; i++) { var object = things.data.insert(Collections.emptyMap()); - inserted.add(object.metadata().uuid()); + inserted.add(object.uuid()); } // Iterate over first 5 objects @@ -114,7 +114,7 @@ public void testWithQueryOptions() throws IOException { var inserted = new ArrayList(); for (var i = 0; i < count; i++) { var object = things.data.insert(Collections.emptyMap()); - inserted.add(object.metadata().uuid()); + inserted.add(object.uuid()); } // Act / Assert diff --git a/src/it/java/io/weaviate/integration/ReferencesITest.java b/src/it/java/io/weaviate/integration/ReferencesITest.java index 6e9016cdd..c8b51acc3 100644 --- a/src/it/java/io/weaviate/integration/ReferencesITest.java +++ b/src/it/java/io/weaviate/integration/ReferencesITest.java @@ -11,12 +11,11 @@ import io.weaviate.ConcurrentTest; import io.weaviate.client6.v1.api.WeaviateClient; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Property; import io.weaviate.client6.v1.api.collections.ReferenceProperty; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.data.Reference; import io.weaviate.client6.v1.api.collections.query.QueryReference; +import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject; import io.weaviate.containers.Container; /** @@ -74,7 +73,7 @@ public void testReferences() throws IOException { Map.of("name", "Alex"), opt -> opt .reference("hasAwards", Reference.uuids( - grammy_1.metadata().uuid(), oscar_1.metadata().uuid())) + grammy_1.uuid(), oscar_1.uuid())) .reference("hasAwards", Reference.objects(grammy_2, oscar_2))); // Act: add one more reference @@ -91,7 +90,7 @@ public void testReferences() throws IOException { .extracting(ReferenceProperty::dataTypes, InstanceOfAssertFactories.list(String.class)) .containsOnly(nsMovies); - var gotAlex = artists.query.fetchObjectById(alex.metadata().uuid(), + var gotAlex = artists.query.fetchObjectById(alex.uuid(), opt -> opt.returnReferences( QueryReference.multi("hasAwards", nsOscar), QueryReference.multi("hasAwards", nsGrammy))); @@ -99,12 +98,12 @@ public void testReferences() throws IOException { Assertions.assertThat(gotAlex).get() .as("Artists: fetch by id including hasAwards references") - // Cast references to Map> - .extracting(WeaviateObject::references, InstanceOfAssertFactories.map(String.class, List.class)) + // Cast references to Map> + .extracting(ReadWeaviateObject::references, InstanceOfAssertFactories.map(String.class, List.class)) .as("hasAwards object reference").extractingByKey("hasAwards") - .asInstanceOf(InstanceOfAssertFactories.list(WeaviateObject.class)) + .asInstanceOf(InstanceOfAssertFactories.list(ReadWeaviateObject.class)) - .extracting(object -> ((ObjectMetadata) object.metadata()).uuid()) + .extracting(object -> object.uuid()) .containsOnly( // INVESTIGATE: When references to 2+ collections are requested, // seems to Weaviate only return references to the first one in the list. @@ -112,7 +111,7 @@ public void testReferences() throws IOException { // so the latter will not be in the response. // // grammy_1.metadata().id(), grammy_2.metadata().id(), - oscar_1.metadata().uuid(), oscar_2.metadata().uuid()); + oscar_1.uuid(), oscar_2.uuid()); } @Test @@ -155,7 +154,7 @@ public void testNestedReferences() throws IOException { .reference("hasAwards", Reference.objects(grammy_1))); // Assert: fetch nested references - var gotAlex = artists.query.fetchObjectById(alex.metadata().uuid(), + var gotAlex = artists.query.fetchObjectById(alex.uuid(), opt -> opt.returnReferences( QueryReference.single("hasAwards", ref -> ref @@ -166,20 +165,20 @@ public void testNestedReferences() throws IOException { Assertions.assertThat(gotAlex).get() .as("Artists: fetch by id including nested references") - // Cast references to Map> - .extracting(WeaviateObject::references, InstanceOfAssertFactories.map(String.class, List.class)) + // Cast references to Map> + .extracting(ReadWeaviateObject::references, InstanceOfAssertFactories.map(String.class, List.class)) .as("hasAwards object reference").extractingByKey("hasAwards") - .asInstanceOf(InstanceOfAssertFactories.list(WeaviateObject.class)) + .asInstanceOf(InstanceOfAssertFactories.list(ReadWeaviateObject.class)) .hasSize(1).allSatisfy(award -> Assertions.assertThat(award) - .returns(grammy_1.metadata().uuid(), grammy -> ((ObjectMetadata) grammy.metadata()).uuid()) + .returns(grammy_1.uuid(), grammy -> grammy.uuid()) - // Cast references to Map> - .extracting(WeaviateObject::references, InstanceOfAssertFactories.map(String.class, List.class)) + // Cast references to Map> + .extracting(ReadWeaviateObject::references, InstanceOfAssertFactories.map(String.class, List.class)) .as("presentedBy object reference").extractingByKey("presentedBy") - .asInstanceOf(InstanceOfAssertFactories.list(WeaviateObject.class)) + .asInstanceOf(InstanceOfAssertFactories.list(ReadWeaviateObject.class)) - .hasSize(1).extracting(WeaviateObject::properties) + .hasSize(1).extracting(ReadWeaviateObject::properties) .allSatisfy(properties -> Assertions.assertThat(properties) .asInstanceOf(InstanceOfAssertFactories.map(String.class, Object.class)) .containsEntry("ceo", "Harvy Mason"))); diff --git a/src/it/java/io/weaviate/integration/SearchITest.java b/src/it/java/io/weaviate/integration/SearchITest.java index 3d3e73964..d37a6718c 100644 --- a/src/it/java/io/weaviate/integration/SearchITest.java +++ b/src/it/java/io/weaviate/integration/SearchITest.java @@ -22,15 +22,14 @@ import io.weaviate.client6.v1.api.WeaviateApiException; import io.weaviate.client6.v1.api.WeaviateClient; import io.weaviate.client6.v1.api.collections.Generative; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Property; import io.weaviate.client6.v1.api.collections.ReferenceProperty; import io.weaviate.client6.v1.api.collections.Reranker; import io.weaviate.client6.v1.api.collections.VectorConfig; import io.weaviate.client6.v1.api.collections.Vectors; import io.weaviate.client6.v1.api.collections.WeaviateMetadata; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.data.Reference; +import io.weaviate.client6.v1.api.collections.data.WriteWeaviateObject; import io.weaviate.client6.v1.api.collections.generate.GenerativeObject; import io.weaviate.client6.v1.api.collections.generate.TaskOutput; import io.weaviate.client6.v1.api.collections.generative.DummyGenerative; @@ -39,6 +38,7 @@ import io.weaviate.client6.v1.api.collections.query.Metadata; import io.weaviate.client6.v1.api.collections.query.QueryMetadata; import io.weaviate.client6.v1.api.collections.query.QueryResponseGroup; +import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject; import io.weaviate.client6.v1.api.collections.query.Rerank; import io.weaviate.client6.v1.api.collections.query.SortBy; import io.weaviate.client6.v1.api.collections.query.Target; @@ -134,7 +134,7 @@ private static Map populateTest(int n) throws IOException { .uuid(randomUUID()) .vectors(Vectors.of(VECTOR_INDEX, vector))); - created.put(object.metadata().uuid(), vector); + created.put(object.uuid(), vector); } return created; @@ -168,11 +168,11 @@ public void testNearText() throws IOException { opt -> opt .distance(0.9f) .moveTo(.98f, to -> to.concepts("tropical")) - .moveAway(.4f, away -> away.uuids(submarine.metadata().uuid())) + .moveAway(.4f, away -> away.uuids(submarine.uuid())) .returnProperties("title")); Assertions.assertThat(result.objects()).hasSize(2) - .extracting(WeaviateObject::properties).allSatisfy( + .extracting(ReadWeaviateObject::properties).allSatisfy( properties -> Assertions.assertThat(properties) .allSatisfy((_k, v) -> Assertions.assertThat((String) v).contains("Jungle"))); } @@ -210,8 +210,8 @@ public void testNearText_groupBy() throws IOException { Assertions.assertThat(result.groups()).hasSize(2) .containsOnlyKeys( - "weaviate://localhost/%s/%s".formatted(nsArtists, beatles.metadata().uuid()), - "weaviate://localhost/%s/%s".formatted(nsArtists, ccr.metadata().uuid())); + "weaviate://localhost/%s/%s".formatted(nsArtists, beatles.uuid()), + "weaviate://localhost/%s/%s".formatted(nsArtists, ccr.uuid())); } @Test @@ -235,7 +235,7 @@ public void testNearImage() throws IOException { opt -> opt.returnProperties("breed")); Assertions.assertThat(got.objects()).hasSize(1).first() - .extracting(WeaviateObject::properties, InstanceOfAssertFactories.MAP) + .extracting(ReadWeaviateObject::properties, InstanceOfAssertFactories.MAP) .extractingByKey("breed").isEqualTo("ragdoll"); } @@ -267,9 +267,9 @@ public void testFetchObjectsWithFilters() throws IOException { Assertions.assertThat(got.objects()) .extracting(hat -> hat.metadata().uuid()) .containsOnly( - redHat.metadata().uuid(), - greenHat.metadata().uuid(), - hugeHat.metadata().uuid()); + redHat.uuid(), + greenHat.uuid(), + hugeHat.uuid()); } @@ -294,7 +294,7 @@ public void testFetchObjectsWithSort() throws Exception { Assertions.assertThat(asc.objects()) .as("value asc") .hasSize(3) - .extracting(WeaviateObject::properties) + .extracting(ReadWeaviateObject::properties) .extracting(object -> object.get("value")) .containsExactly(1L, 2L, 3L); @@ -305,7 +305,7 @@ public void testFetchObjectsWithSort() throws Exception { Assertions.assertThat(desc.objects()) .as("value desc") .hasSize(3) - .extracting(WeaviateObject::properties) + .extracting(ReadWeaviateObject::properties) .extracting(object -> object.get("value")) .containsExactly(3L, 2L, 1L); } @@ -331,8 +331,8 @@ public void testBm25() throws IOException, InterruptedException, ExecutionExcept Assertions.assertThat(dollarWorlds.objects()) .hasSize(1) - .extracting(WeaviateObject::metadata).extracting(QueryMetadata::uuid) - .containsOnly(want.metadata().uuid()); + .extracting(ReadWeaviateObject::metadata).extracting(QueryMetadata::uuid) + .containsOnly(want.uuid()); } /** @@ -363,8 +363,8 @@ public void testBm25_async() throws Exception, InterruptedException, ExecutionEx Assertions.assertThat(dollarWorlds.objects()) .hasSize(1) - .extracting(WeaviateObject::metadata).extracting(QueryMetadata::uuid) - .containsOnly(want.metadata().uuid()); + .extracting(ReadWeaviateObject::metadata).extracting(QueryMetadata::uuid) + .containsOnly(want.uuid()); } } @@ -387,14 +387,14 @@ public void testNearObject() throws IOException { animals.data.insert(Map.of("kind", "dolphin")); // Act - var terrestrial = animals.query.nearObject(cat.metadata().uuid(), + var terrestrial = animals.query.nearObject(cat.uuid(), q -> q.excludeSelf().limit(1)); // Assert Assertions.assertThat(terrestrial.objects()) .hasSize(1) - .extracting(WeaviateObject::metadata).extracting(WeaviateMetadata::uuid) - .containsOnly(lion.metadata().uuid()); + .extracting(ReadWeaviateObject::metadata).extracting(WeaviateMetadata::uuid) + .containsOnly(lion.uuid()); } @Test @@ -420,8 +420,8 @@ public void testHybrid() throws IOException { // Assert Assertions.assertThat(winterSport.objects()) .hasSize(1) - .extracting(WeaviateObject::metadata).extracting(WeaviateMetadata::uuid) - .containsOnly(skiing.metadata().uuid()); + .extracting(ReadWeaviateObject::metadata).extracting(WeaviateMetadata::uuid) + .containsOnly(skiing.uuid()); var first = winterSport.objects().get(0); Assertions.assertThat(first.metadata().score()) @@ -490,7 +490,7 @@ public void test_includeVectors() throws IOException { // Assert Assertions.assertThat(got).get() - .extracting(WeaviateObject::vectors) + .extracting(ReadWeaviateObject::vectors) .returns(true, v -> v.contains("v1")) .returns(true, v -> v.contains("v2")) .returns(false, v -> v.contains("v3")); @@ -519,7 +519,7 @@ public void testMetadataAll() throws IOException { // Assert var metadataHybrid = Assertions.assertThat(gotHybrid.objects()) .hasSize(1) - .extracting(WeaviateObject::metadata) + .extracting(ReadWeaviateObject::metadata) .first().actual(); Assertions.assertThat(metadataHybrid.uuid()).as("uuid").isNotNull().isEqualTo(frisbee.uuid()); @@ -530,7 +530,7 @@ public void testMetadataAll() throws IOException { var metadataNearText = Assertions.assertThat(gotNearText.objects()) .hasSize(1) - .extracting(WeaviateObject::metadata) + .extracting(ReadWeaviateObject::metadata) .first().actual(); Assertions.assertThat(metadataNearText.uuid()).as("uuid").isNotNull().isEqualTo(frisbee.uuid()); @@ -558,12 +558,10 @@ public void testNearVector_targetVectors() throws IOException { Vectors.of("v2d", new float[][] { { 1, 2, 3 }, { 1, 2, 3 } }))); var thing456 = things.data.insertMany(List.of( - WeaviateObject.of(thing -> thing - .metadata(ObjectMetadata.of( - meta -> meta - .vectors( - Vectors.of("v1d", new float[] { 4, 5, 6 }), - Vectors.of("v2d", new float[][] { { 4, 5, 6 }, { 4, 5, 6 } }))))))); + WriteWeaviateObject.of(thing -> thing + .vectors( + Vectors.of("v1d", new float[] { 4, 5, 6 }), + Vectors.of("v2d", new float[][] { { 4, 5, 6 }, { 4, 5, 6 } }))))); Assertions.assertThat(thing456.errors()).as("insert many").isEmpty(); // Act @@ -572,7 +570,7 @@ public void testNearVector_targetVectors() throws IOException { q -> q.limit(1)); Assertions.assertThat(got123.objects()) .as("search v1d") - .hasSize(1).extracting(WeaviateObject::uuid) + .hasSize(1).extracting(ReadWeaviateObject::uuid) .containsExactly(thing123.uuid()); var got456 = things.query.nearVector( @@ -580,7 +578,7 @@ public void testNearVector_targetVectors() throws IOException { q -> q.limit(1)); Assertions.assertThat(got456.objects()) .as("search v2d") - .hasSize(1).extracting(WeaviateObject::uuid) + .hasSize(1).extracting(ReadWeaviateObject::uuid) .containsExactly(thing456.uuids().get(0)); } @@ -762,9 +760,8 @@ public void test_maxGrpcMessageSize() throws Exception { .vectorConfig(VectorConfig.selfProvided())); final var vector = randomVector(5000, -.01f, .01f); - final WeaviateObject, Reference, ObjectMetadata> hugeObject = WeaviateObject.of(obj -> obj - .metadata(ObjectMetadata.of(m -> m - .vectors(Vectors.of(vector))))); + final WriteWeaviateObject> hugeObject = WriteWeaviateObject.of( + obj -> obj.vectors(Vectors.of(vector))); Assertions.assertThatThrownBy(() -> { // insertMany to route this request through gRPC. diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionConfig.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionConfig.java index 03c66841b..aabe4a7cf 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionConfig.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionConfig.java @@ -33,7 +33,7 @@ public record CollectionConfig( List references, /** Vector indexes configured for this collection. */ @SerializedName("vectorConfig") Map vectors, - /** Multi-tenantcy options. */ + /** Multi-tenancy options. */ @SerializedName("multiTenancyConfig") MultiTenancy multiTenancy, /** Sharding configuration. */ @SerializedName("shardingConfig") Sharding sharding, @@ -193,14 +193,13 @@ public Builder sharding(Function> fn) } /** Configure multi-tenancy. */ - public Builder multiTenancy(MultiTenancy multiTenancy) { - this.multiTenancy = multiTenancy; - return this; + public Builder multiTenancy(Function> fn) { + return multiTenancy(MultiTenancy.of(fn)); } /** Configure multi-tenancy. */ - public Builder multiTenancy(Function> fn) { - this.multiTenancy = MultiTenancy.of(fn); + public Builder multiTenancy(MultiTenancy multiTenancy) { + this.multiTenancy = multiTenancy; return this; } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/ObjectMetadata.java b/src/main/java/io/weaviate/client6/v1/api/collections/ObjectMetadata.java index 4dcaed6a5..e467644c7 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/ObjectMetadata.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/ObjectMetadata.java @@ -11,7 +11,7 @@ public record ObjectMetadata( @SerializedName("id") String uuid, @SerializedName("vectors") Vectors vectors, @SerializedName("creationTimeUnix") Long createdAt, - @SerializedName("lastUpdateTImeUnix") Long lastUpdatedAt) implements WeaviateMetadata { + @SerializedName("lastUpdateTimeUnix") Long lastUpdatedAt) implements WeaviateMetadata { public ObjectMetadata(Builder builder) { this(builder.uuid, builder.vectors, null, null); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/Vectors.java b/src/main/java/io/weaviate/client6/v1/api/collections/Vectors.java index a1e9e8796..1a0b3203b 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/Vectors.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/Vectors.java @@ -81,6 +81,20 @@ public Vectors(Vectors... vectors) { this.vectorsMap = namedVectors; } + /** + * Add more vector objects. + * + * @param vectors Vector objects. + * @return A new {@code Vectors} object containing all vectors. + */ + public Vectors withVectors(Vectors... vectors) { + var combined = new HashMap<>(vectorsMap); + for (var v : vectors) { + combined.putAll(v.vectorsMap); + } + return new Vectors(combined); + } + /** * Check if a vector exists in the query result. * @@ -90,6 +104,11 @@ public boolean contains(String name) { return vectorsMap.containsKey(name); } + /** Returns the number of vectors contained. */ + public int size() { + return vectorsMap.size(); + } + /** * Get 1-dimensional vector by name. * diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateObject.java b/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateObject.java index c320cb20f..dedc38849 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateObject.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateObject.java @@ -1,195 +1,9 @@ package io.weaviate.client6.v1.api.collections; -import java.io.IOException; -import java.lang.reflect.ParameterizedType; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; +public interface WeaviateObject { + String uuid(); -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.TypeAdapter; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.internal.Streams; -import com.google.gson.reflect.TypeToken; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; + String collection(); -import io.weaviate.client6.v1.internal.ObjectBuilder; - -public record WeaviateObject( - String collection, - P properties, - Map> references, - M metadata) { - - /** Shorthand for accessing objects's UUID from metadata. */ - public String uuid() { - return metadata.uuid(); - } - - /** Shorthand for accessing objects's vectors from metadata. */ - public Vectors vectors() { - return metadata.vectors(); - } - - public static WeaviateObject of( - Function, ObjectBuilder>> fn) { - return fn.apply(new Builder<>()).build(); - } - - public WeaviateObject(Builder builder) { - this(builder.collectionName, builder.properties, builder.references, builder.metadata); - } - - public static class Builder implements ObjectBuilder> { - private String collectionName; - private P properties; - private Map> references = new HashMap<>(); - private M metadata; - - /** Set the name of the collection his object belongs to. */ - public final Builder collection(String collectionName) { - this.collectionName = collectionName; - return this; - } - - /** Add object properties. */ - public final Builder properties(P properties) { - this.properties = properties; - return this; - } - - /** - * Add a reference. Calls to {@link #reference} can be chained - * to add multiple references. - */ - @SafeVarargs - public final Builder reference(String property, R... references) { - for (var ref : references) { - addReference(property, ref); - } - return this; - } - - private final void addReference(String property, R reference) { - if (!references.containsKey(property)) { - references.put(property, new ArrayList<>()); - } - references.get(property).add(reference); - } - - public Builder references(Map> references) { - this.references = references; - return this; - } - - public Builder metadata(M metadata) { - this.metadata = metadata; - return this; - } - - @Override - public WeaviateObject build() { - return new WeaviateObject<>(this); - } - } - - public static enum CustomTypeAdapterFactory implements TypeAdapterFactory { - INSTANCE; - - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken typeToken) { - var type = typeToken.getType(); - var rawType = typeToken.getRawType(); - if (rawType != WeaviateObject.class || - !(type instanceof ParameterizedType parameterized) - || parameterized.getActualTypeArguments().length < 3) { - return null; - } - - var typeParams = parameterized.getActualTypeArguments(); - final var propertiesType = typeParams[0]; - final var referencesType = typeParams[1]; - final var metadataType = typeParams[2]; - - final var propertiesAdapter = gson.getAdapter(TypeToken.get(propertiesType)); - final var metadataAdapter = gson.getAdapter(TypeToken.get(metadataType)); - final var referencesAdapter = gson.getAdapter(TypeToken.get(referencesType)); - - return (TypeAdapter) new TypeAdapter>() { - - @Override - public void write(JsonWriter out, WeaviateObject value) throws IOException { - out.beginObject(); - - out.name("class"); - out.value(value.collection()); - - out.name("properties"); - if (value.references().isEmpty()) { - ((TypeAdapter) propertiesAdapter).write(out, value.properties()); - } else { - var properties = ((TypeAdapter) propertiesAdapter).toJsonTree(value.properties()).getAsJsonObject(); - for (var refEntry : value.references().entrySet()) { - var beacons = new JsonArray(); - for (var reference : (List) refEntry.getValue()) { - var beacon = ((TypeAdapter) referencesAdapter).toJsonTree(reference); - beacons.add(beacon); - } - properties.add(refEntry.getKey(), beacons); - } - Streams.write(properties, out); - } - - // Flatten out metadata fields. - var metadata = ((TypeAdapter) metadataAdapter).toJsonTree(value.metadata); - for (var entry : metadata.getAsJsonObject().entrySet()) { - out.name(entry.getKey()); - Streams.write(entry.getValue(), out); - } - out.endObject(); - } - - @Override - public WeaviateObject read(JsonReader in) throws IOException { - var builder = new WeaviateObject.Builder<>(); - var metadata = new ObjectMetadata.Builder(); - - var object = JsonParser.parseReader(in).getAsJsonObject(); - builder.collection(object.get("class").getAsString()); - - var jsonProperties = object.get("properties").getAsJsonObject(); - var trueProperties = new JsonObject(); - for (var property : jsonProperties.entrySet()) { - var value = property.getValue(); - if (!value.isJsonArray()) { - trueProperties.add(property.getKey(), value); - continue; - } - var array = value.getAsJsonArray(); - var first = array.get(0); - if (first.isJsonObject() && first.getAsJsonObject().has("beacon")) { - for (var el : array) { - var beacon = ((TypeAdapter) referencesAdapter).fromJsonTree(el); - builder.reference(property.getKey(), beacon); - } - } - } - - builder.properties(propertiesAdapter.fromJsonTree(trueProperties)); - - metadata.uuid(object.get("id").getAsString()); - builder.metadata(metadata.build()); - - return builder.build(); - } - }.nullSafe(); - } - } + Vectors vectors(); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/BatchReference.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/BatchReference.java index 8e14a04ec..9854a57bc 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/BatchReference.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/BatchReference.java @@ -11,20 +11,20 @@ public record BatchReference(String fromCollection, String fromProperty, String fromUuid, Reference reference) { - public static BatchReference[] objects(WeaviateObject fromObject, String fromProperty, - WeaviateObject... toObjects) { + public static BatchReference[] objects(WeaviateObject fromObject, String fromProperty, + WeaviateObject... toObjects) { return Arrays.stream(toObjects) .map(to -> new BatchReference( - fromObject.collection(), fromProperty, fromObject.metadata().uuid(), + fromObject.collection(), fromProperty, fromObject.uuid(), Reference.object(to))) .toArray(BatchReference[]::new); } - public static BatchReference[] uuids(WeaviateObject fromObject, String fromProperty, + public static BatchReference[] uuids(WeaviateObject fromObject, String fromProperty, String... toUuids) { return Arrays.stream(toUuids) .map(to -> new BatchReference( - fromObject.collection(), fromProperty, fromObject.metadata().uuid(), + fromObject.collection(), fromProperty, fromObject.uuid(), Reference.uuids(to))) .toArray(BatchReference[]::new); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java index c41a51057..843bdbb02 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java @@ -9,9 +9,7 @@ import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.api.collections.GeoCoordinates; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.PhoneNumber; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.MapUtil; import io.weaviate.client6.v1.internal.grpc.ByteStringUtil; import io.weaviate.client6.v1.internal.grpc.Rpc; @@ -22,25 +20,25 @@ import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBatch; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; -public record InsertManyRequest(List> objects) { +public record InsertManyRequest(List> objects) { @SafeVarargs - public InsertManyRequest(WeaviateObject... objects) { + public InsertManyRequest(WriteWeaviateObject... objects) { this(Arrays.asList(objects)); } + @SuppressWarnings("unchecked") @SafeVarargs - public static final InsertManyRequest of(T... properties) { + public static final InsertManyRequest of(PropertiesT... properties) { var objects = Arrays.stream(properties) - .map(p -> WeaviateObject.of( - obj -> obj.properties(p).metadata(ObjectMetadata.of()))) + .map(p -> (WriteWeaviateObject) WriteWeaviateObject.of(obj -> obj.properties(p))) .toList(); - return new InsertManyRequest(objects); + return new InsertManyRequest<>(objects); } - public static Rpc, WeaviateProtoBatch.BatchObjectsRequest, InsertManyResponse, WeaviateProtoBatch.BatchObjectsReply> rpc( - List> insertObjects, - CollectionDescriptor collection, + public static Rpc, WeaviateProtoBatch.BatchObjectsRequest, InsertManyResponse, WeaviateProtoBatch.BatchObjectsReply> rpc( + List> insertObjects, + CollectionDescriptor collection, CollectionHandleDefaults defaults) { return Rpc.insert( request -> { @@ -75,8 +73,8 @@ public static Rpc, WeaviateProtoBatch.BatchObjectsReque while (iter.hasNext()) { var idx = iter.nextIndex(); var next = iter.next(); - var uuid = next.metadata() != null ? next.metadata().uuid() : null; + var uuid = next.uuid(); if (failed.containsKey(idx)) { var err = failed.get(idx); errors.add(err); @@ -94,72 +92,66 @@ public static Rpc, WeaviateProtoBatch.BatchObjectsReque } public static void buildObject(WeaviateProtoBatch.BatchObject.Builder object, - WeaviateObject insert, + WriteWeaviateObject insert, CollectionDescriptor collection, CollectionHandleDefaults defaults) { object.setCollection(collection.collectionName()); - var metadata = insert.metadata(); - if (metadata != null) { - object.setUuid(metadata.uuid()); - - if (metadata.vectors() != null) { - var vectors = metadata.vectors().asMap() - .entrySet().stream().map(entry -> { - var value = entry.getValue(); - var vector = WeaviateProtoBase.Vectors.newBuilder() - .setName(entry.getKey()); - - if (value instanceof float[] single) { - vector.setType(VectorType.VECTOR_TYPE_SINGLE_FP32); - vector.setVectorBytes(ByteStringUtil.encodeVectorSingle(single)); - } else if (value instanceof float[][] multi) { - vector.setVectorBytes(ByteStringUtil.encodeVectorMulti(multi)); - vector.setType(VectorType.VECTOR_TYPE_MULTI_FP32); - } - - return vector.build(); - }).toList(); - object.addAllVectors(vectors); - } - if (defaults.tenant() != null) { - object.setTenant(defaults.tenant()); - } + if (insert.uuid() != null) { + object.setUuid(insert.uuid()); + } + + if (insert.vectors() != null) { + var vectors = insert.vectors().asMap() + .entrySet().stream().map(entry -> { + var value = entry.getValue(); + var vector = WeaviateProtoBase.Vectors.newBuilder() + .setName(entry.getKey()); + + if (value instanceof float[] single) { + vector.setType(VectorType.VECTOR_TYPE_SINGLE_FP32); + vector.setVectorBytes(ByteStringUtil.encodeVectorSingle(single)); + } else if (value instanceof float[][] multi) { + vector.setVectorBytes(ByteStringUtil.encodeVectorMulti(multi)); + vector.setType(VectorType.VECTOR_TYPE_MULTI_FP32); + } + + return vector.build(); + }).toList(); + object.addAllVectors(vectors); + } + if (defaults.tenant() != null) { + object.setTenant(defaults.tenant()); } var singleRef = new ArrayList(); var multiRef = new ArrayList(); - insert.references() - .entrySet().stream().forEach(entry -> { - var references = entry.getValue(); - - // dyma: How are we supposed to know if the reference - // is single- or multi-target? - for (var ref : references) { - if (ref.collection() == null) { - singleRef.add( - WeaviateProtoBatch.BatchObject.SingleTargetRefProps.newBuilder() - .addAllUuids(ref.uuids()) - .setPropName(entry.getKey()) - .build()); - } else { - multiRef.add( - WeaviateProtoBatch.BatchObject.MultiTargetRefProps.newBuilder() - .setTargetCollection(ref.collection()) - .addAllUuids(ref.uuids()) - .setPropName(entry.getKey()) - .build()); - } + if (insert.references() != null) { + insert.references().entrySet().stream().forEach(entry -> { + var references = entry.getValue(); + + // dyma: How are we supposed to know if the reference + // is single- or multi-target? + for (var ref : references) { + if (ref.collection() == null) { + singleRef.add(WeaviateProtoBatch.BatchObject.SingleTargetRefProps.newBuilder().addAllUuids(ref.uuids()) + .setPropName(entry.getKey()).build()); + } else { + multiRef.add(WeaviateProtoBatch.BatchObject.MultiTargetRefProps.newBuilder() + .setTargetCollection(ref.collection()).addAllUuids(ref.uuids()).setPropName(entry.getKey()).build()); } - }); + } + }); + } var properties = WeaviateProtoBatch.BatchObject.Properties.newBuilder() .addAllSingleTargetRefProps(singleRef) .addAllMultiTargetRefProps(multiRef); if (insert.properties() != null) { - var nonRef = marshalStruct(collection.propertiesReader(insert.properties()).readProperties()); + var nonRef = marshalStruct(collection.propertiesReader(insert.properties()) + .readProperties()); properties.setNonRefProperties(nonRef); } object.setProperties(properties); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertObjectRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertObjectRequest.java index fc57c2882..cf992eba7 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertObjectRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertObjectRequest.java @@ -7,21 +7,22 @@ import com.google.gson.reflect.TypeToken; import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; -import io.weaviate.client6.v1.api.collections.Vectors; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.json.JSON; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; import io.weaviate.client6.v1.internal.rest.Endpoint; import io.weaviate.client6.v1.internal.rest.SimpleEndpoint; -public record InsertObjectRequest(WeaviateObject object) { +public record InsertObjectRequest(WriteWeaviateObject object) { @SuppressWarnings("unchecked") - public static final Endpoint, WeaviateObject> endpoint( - CollectionDescriptor collection, + public static final Endpoint, WriteWeaviateObject> endpoint( + CollectionDescriptor collection, CollectionHandleDefaults defaults) { + + final var typeToken = (TypeToken>) TypeToken + .getParameterized(WriteWeaviateObject.class, collection.typeToken().getType()); + return new SimpleEndpoint<>( request -> "POST", request -> "/objects/", @@ -29,55 +30,26 @@ public static final Endpoint, WeaviateObject JSON.serialize( - new WriteWeaviateObject<>(request.object, defaults.tenant()), - TypeToken.getParameterized( - WriteWeaviateObject.class, collection.typeToken().getType())), - (statusCode, response) -> JSON.deserialize(response, - (TypeToken>) TypeToken.getParameterized( - WeaviateObject.class, collection.typeToken().getType(), Object.class, ObjectMetadata.class))); - } - - public static InsertObjectRequest of(String collectionName, T properties) { - return of(collectionName, properties, ObjectBuilder.identity()); - } - - public static InsertObjectRequest of(String collectionName, T properties, - Function, ObjectBuilder>> fn) { - return fn.apply(new Builder(collectionName, properties)).build(); + new WriteWeaviateObject<>( + request.object.uuid(), + collection.collectionName(), + defaults.tenant(), + request.object.properties(), + request.object.vectors(), + request.object.createdAt(), + request.object.lastUpdatedAt(), + request.object.references()), + typeToken), + (statusCode, response) -> JSON.deserialize(response, typeToken)); } - public InsertObjectRequest(Builder builder) { - this(builder.object.build()); + static InsertObjectRequest of(PropertiesT properties) { + return of(properties, ObjectBuilder.identity()); } - public static class Builder implements ObjectBuilder> { - private final WeaviateObject.Builder object = new WeaviateObject.Builder<>(); - private final ObjectMetadata.Builder metadata = new ObjectMetadata.Builder(); - - public Builder(String collectionName, T properties) { - this.object.collection(collectionName).properties(properties); - } - - public Builder uuid(String uuid) { - this.metadata.uuid(uuid); - return this; - } - - public Builder vectors(Vectors... vectors) { - this.metadata.vectors(vectors); - return this; - } - - public Builder reference(String property, Reference... references) { - this.object.reference(property, references); - return this; - } - - @Override - public InsertObjectRequest build() { - this.object.metadata(this.metadata.build()); - return new InsertObjectRequest<>(this); - } + static InsertObjectRequest of( + PropertiesT properties, + Function, ObjectBuilder>> fn) { + return new InsertObjectRequest<>(WriteWeaviateObject.of(ObjectBuilder.partial(fn, b -> b.properties(properties)))); } - } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/Reference.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/Reference.java index 3a4206feb..097478788 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/Reference.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/Reference.java @@ -6,6 +6,7 @@ import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import io.weaviate.client6.v1.api.collections.WeaviateObject; @@ -28,14 +29,14 @@ public static Reference uuids(String... uuids) { } /** Create references to single {@link WeaviateObject}. */ - public static Reference object(WeaviateObject object) { - return new Reference(object.collection(), object.metadata().uuid()); + public static Reference object(WeaviateObject object) { + return new Reference(object.collection(), object.uuid()); } /** Create references to multiple {@link WeaviateObject}. */ - public static Reference[] objects(WeaviateObject... objects) { + public static Reference[] objects(WeaviateObject... objects) { return Arrays.stream(objects) - .map(o -> new Reference(o.collection(), o.metadata().uuid())) + .map(o -> new Reference(o.collection(), o.uuid())) .toArray(Reference[]::new); } @@ -80,6 +81,12 @@ public Reference read(JsonReader in) throws IOException { in.beginObject(); in.nextName(); // expect "beacon"? var beacon = in.nextString(); + + // Skip to the end of the object. There's going to be the "href" + // key too, which is irrelevant for us. + while (in.peek() != JsonToken.END_OBJECT) { + in.skipValue(); + } in.endObject(); beacon = beacon.replaceFirst("weaviate://localhost/", ""); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddRequest.java index 21321327f..00a04c654 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddRequest.java @@ -17,6 +17,5 @@ public static final Endpoint endpoint( + request.fromProperty, request -> defaults.queryParameters(), request -> JSON.serialize(request.reference)); - } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReplaceObjectRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReplaceObjectRequest.java index 2a3257d14..d3d1ec31f 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReplaceObjectRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReplaceObjectRequest.java @@ -7,66 +7,74 @@ import com.google.gson.reflect.TypeToken; import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Vectors; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.json.JSON; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; import io.weaviate.client6.v1.internal.rest.Endpoint; import io.weaviate.client6.v1.internal.rest.SimpleEndpoint; -public record ReplaceObjectRequest(WeaviateObject object) { +public record ReplaceObjectRequest(WriteWeaviateObject object) { - static final Endpoint, Void> endpoint(CollectionDescriptor collection, + static final Endpoint, Void> endpoint( + CollectionDescriptor collection, CollectionHandleDefaults defaults) { + + final var typeToken = TypeToken.getParameterized(WriteWeaviateObject.class, collection.typeToken().getType()); + return SimpleEndpoint.sideEffect( request -> "PUT", - request -> "/objects/" + collection.collectionName() + "/" + request.object.metadata().uuid(), + request -> "/objects/" + collection.collectionName() + "/" + request.object.uuid(), request -> defaults.consistencyLevel() != null ? Map.of("consistency_level", defaults.consistencyLevel()) : Collections.emptyMap(), request -> JSON.serialize( - new WriteWeaviateObject<>(request.object, defaults.tenant()), - TypeToken.getParameterized(WriteWeaviateObject.class, collection.typeToken().getType()))); + new WriteWeaviateObject<>( + request.object.uuid(), + collection.collectionName(), + defaults.tenant(), + request.object.properties(), + request.object.vectors(), + request.object.createdAt(), + request.object.lastUpdatedAt(), + request.object.references()), + typeToken)); } - public static ReplaceObjectRequest of(String collectionName, String uuid, - Function, ObjectBuilder>> fn) { - return fn.apply(new Builder<>(collectionName, uuid)).build(); + public static ReplaceObjectRequest of( + String uuid, + Function, ObjectBuilder>> fn) { + return fn.apply(new Builder<>(uuid)).build(); } - public ReplaceObjectRequest(Builder builder) { + public ReplaceObjectRequest(Builder builder) { this(builder.object.build()); } - public static class Builder implements ObjectBuilder> { - private final WeaviateObject.Builder object = new WeaviateObject.Builder<>(); - private final ObjectMetadata.Builder metadata = new ObjectMetadata.Builder(); + public static class Builder implements ObjectBuilder> { + private final WriteWeaviateObject.Builder object = new WriteWeaviateObject.Builder<>(); - public Builder(String collectionName, String uuid) { - this.object.collection(collectionName); - this.metadata.uuid(uuid); + public Builder(String uuid) { + this.object.uuid(uuid); } - public Builder properties(T properties) { + public Builder properties(PropertiesT properties) { this.object.properties(properties); return this; } - public Builder vectors(Vectors... vectors) { - this.metadata.vectors(vectors); + public Builder vectors(Vectors... vectors) { + this.object.vectors(vectors); return this; } - public Builder reference(String property, Reference... references) { + public Builder reference(String property, Reference... references) { this.object.reference(property, references); return this; } @Override - public ReplaceObjectRequest build() { - this.object.metadata(this.metadata.build()); + public ReplaceObjectRequest build() { return new ReplaceObjectRequest<>(this); } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/UpdateObjectRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/UpdateObjectRequest.java index c174e05eb..3368468a7 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/UpdateObjectRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/UpdateObjectRequest.java @@ -7,66 +7,73 @@ import com.google.gson.reflect.TypeToken; import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Vectors; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.json.JSON; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; import io.weaviate.client6.v1.internal.rest.Endpoint; import io.weaviate.client6.v1.internal.rest.SimpleEndpoint; -public record UpdateObjectRequest(WeaviateObject object) { +public record UpdateObjectRequest(WriteWeaviateObject object) { - static final Endpoint, Void> endpoint(CollectionDescriptor collection, + static final Endpoint, Void> endpoint( + CollectionDescriptor collection, CollectionHandleDefaults defaults) { + + final var typeToken = TypeToken.getParameterized(WriteWeaviateObject.class, collection.typeToken().getType()); + return SimpleEndpoint.sideEffect( request -> "PATCH", - request -> "/objects/" + collection.collectionName() + "/" + request.object.metadata().uuid(), + request -> "/objects/" + collection.collectionName() + "/" + request.object.uuid(), request -> defaults.consistencyLevel() != null ? Map.of("consistency_level", defaults.consistencyLevel()) : Collections.emptyMap(), request -> JSON.serialize( - new WriteWeaviateObject<>(request.object, defaults.tenant()), - TypeToken.getParameterized(WriteWeaviateObject.class, collection.typeToken().getType()))); + new WriteWeaviateObject<>( + request.object.uuid(), + collection.collectionName(), + defaults.tenant(), + request.object.properties(), + request.object.vectors(), + request.object.createdAt(), + request.object.lastUpdatedAt(), + request.object.references()), + typeToken)); } - public static UpdateObjectRequest of(String collectionName, String uuid, - Function, ObjectBuilder>> fn) { - return fn.apply(new Builder<>(collectionName, uuid)).build(); + public static UpdateObjectRequest of(String uuid, + Function, ObjectBuilder>> fn) { + return fn.apply(new Builder<>(uuid)).build(); } - public UpdateObjectRequest(Builder builder) { + public UpdateObjectRequest(Builder builder) { this(builder.object.build()); } - public static class Builder implements ObjectBuilder> { - private final WeaviateObject.Builder object = new WeaviateObject.Builder<>(); - private final ObjectMetadata.Builder metadata = new ObjectMetadata.Builder(); + public static class Builder implements ObjectBuilder> { + private final WriteWeaviateObject.Builder object = new WriteWeaviateObject.Builder<>(); - public Builder(String collectionName, String uuid) { - this.object.collection(collectionName); - this.metadata.uuid(uuid); + public Builder(String uuid) { + this.object.uuid(uuid); } - public Builder properties(T properties) { + public Builder properties(PropertiesT properties) { this.object.properties(properties); return this; } - public Builder vectors(Vectors... vectors) { - this.metadata.vectors(vectors); + public Builder vectors(Vectors... vectors) { + this.object.vectors(vectors); return this; } - public Builder reference(String property, Reference... references) { + public Builder reference(String property, Reference... references) { this.object.reference(property, references); return this; } @Override - public UpdateObjectRequest build() { - this.object.metadata(this.metadata.build()); + public UpdateObjectRequest build() { return new UpdateObjectRequest<>(this); } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java index c6eb48fe3..953a920d9 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java @@ -6,8 +6,6 @@ import java.util.function.Function; import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.query.WeaviateQueryClient; import io.weaviate.client6.v1.api.collections.query.Filter; import io.weaviate.client6.v1.api.collections.query.FilterOperand; @@ -45,14 +43,20 @@ public WeaviateDataClient(WeaviateDataClient c, CollectionHandleDef this.defaults = defaults; } - public WeaviateObject insert(PropertiesT properties) throws IOException { - return insert(InsertObjectRequest.of(collection.collectionName(), properties)); + public WriteWeaviateObject insert(PropertiesT properties) throws IOException { + return insert(InsertObjectRequest.of(properties)); } - public WeaviateObject insert(PropertiesT properties, - Function, ObjectBuilder>> fn) + public WriteWeaviateObject insert( + PropertiesT properties, + Function, ObjectBuilder>> fn) throws IOException { - return insert(InsertObjectRequest.of(collection.collectionName(), properties, fn)); + return insert(InsertObjectRequest.of(properties, fn)); + } + + public WriteWeaviateObject insert(InsertObjectRequest request) + throws IOException { + return this.restTransport.performRequest(request, InsertObjectRequest.endpoint(collection, defaults)); } @SafeVarargs @@ -60,12 +64,12 @@ public final InsertManyResponse insertMany(PropertiesT... objects) { return insertMany(InsertManyRequest.of(objects)); } - public InsertManyResponse insertMany(List> objects) { + public InsertManyResponse insertMany(List> objects) { return insertMany(new InsertManyRequest<>(objects)); } @SafeVarargs - public final InsertManyResponse insertMany(WeaviateObject... objects) { + public final InsertManyResponse insertMany(WriteWeaviateObject... objects) { return insertMany(Arrays.asList(objects)); } @@ -74,26 +78,23 @@ public InsertManyResponse insertMany(InsertManyRequest request) { InsertManyRequest.rpc(request.objects(), collection, defaults)); } - public WeaviateObject insert(InsertObjectRequest request) - throws IOException { - return this.restTransport.performRequest(request, InsertObjectRequest.endpoint(collection, defaults)); - } - public boolean exists(String uuid) { return this.query.fetchObjectById(uuid).isPresent(); } - public void update(String uuid, + public void update( + String uuid, Function, ObjectBuilder>> fn) throws IOException { - this.restTransport.performRequest(UpdateObjectRequest.of(collection.collectionName(), uuid, fn), + this.restTransport.performRequest(UpdateObjectRequest.of(uuid, fn), UpdateObjectRequest.endpoint(collection, defaults)); } - public void replace(String uuid, + public void replace( + String uuid, Function, ObjectBuilder>> fn) throws IOException { - this.restTransport.performRequest(ReplaceObjectRequest.of(collection.collectionName(), uuid, fn), + this.restTransport.performRequest(ReplaceObjectRequest.of(uuid, fn), ReplaceObjectRequest.endpoint(collection, defaults)); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java index 7ae7f0529..7ac560fc9 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java @@ -8,8 +8,6 @@ import java.util.function.Function; import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.query.WeaviateQueryClientAsync; import io.weaviate.client6.v1.api.collections.query.Filter; import io.weaviate.client6.v1.api.collections.query.FilterOperand; @@ -47,16 +45,17 @@ public WeaviateDataClientAsync(WeaviateDataClientAsync c, Collectio this.defaults = defaults; } - public CompletableFuture> insert(PropertiesT properties) { - return insert(InsertObjectRequest.of(collection.collectionName(), properties)); + public CompletableFuture> insert(PropertiesT properties) { + return insert(InsertObjectRequest.of(properties)); } - public CompletableFuture> insert(PropertiesT properties, - Function, ObjectBuilder>> fn) { - return insert(InsertObjectRequest.of(collection.collectionName(), properties, fn)); + public CompletableFuture> insert( + PropertiesT properties, + Function, ObjectBuilder>> fn) { + return insert(InsertObjectRequest.of(properties, fn)); } - public CompletableFuture> insert( + public CompletableFuture> insert( InsertObjectRequest request) { return this.restTransport.performRequestAsync(request, InsertObjectRequest.endpoint(collection, defaults)); } @@ -67,13 +66,11 @@ public final CompletableFuture insertMany(PropertiesT... obj } @SafeVarargs - public final CompletableFuture insertMany( - WeaviateObject... objects) { + public final CompletableFuture insertMany(WriteWeaviateObject... objects) { return insertMany(Arrays.asList(objects)); } - public CompletableFuture insertMany( - List> objects) { + public CompletableFuture insertMany(List> objects) { return insertMany(new InsertManyRequest<>(objects)); } @@ -86,15 +83,17 @@ public CompletableFuture exists(String uuid) { return this.query.fetchObjectById(uuid).thenApply(Optional::isPresent); } - public CompletableFuture update(String uuid, + public CompletableFuture update( + String uuid, Function, ObjectBuilder>> fn) { - return this.restTransport.performRequestAsync(UpdateObjectRequest.of(collection.collectionName(), uuid, fn), + return this.restTransport.performRequestAsync(UpdateObjectRequest.of(uuid, fn), UpdateObjectRequest.endpoint(collection, defaults)); } - public CompletableFuture replace(String uuid, + public CompletableFuture replace( + String uuid, Function, ObjectBuilder>> fn) { - return this.restTransport.performRequestAsync(ReplaceObjectRequest.of(collection.collectionName(), uuid, fn), + return this.restTransport.performRequestAsync(ReplaceObjectRequest.of(uuid, fn), ReplaceObjectRequest.endpoint(collection, defaults)); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/WriteWeaviateObject.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/WriteWeaviateObject.java index a351e6667..673157532 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/WriteWeaviateObject.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/WriteWeaviateObject.java @@ -2,8 +2,12 @@ import java.io.IOException; import java.lang.reflect.ParameterizedType; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; +import java.util.function.Function; import com.google.gson.Gson; import com.google.gson.JsonArray; @@ -11,23 +15,109 @@ import com.google.gson.JsonParser; import com.google.gson.TypeAdapter; import com.google.gson.TypeAdapterFactory; +import com.google.gson.annotations.SerializedName; import com.google.gson.internal.Streams; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; +import io.weaviate.client6.v1.api.collections.Vectors; import io.weaviate.client6.v1.api.collections.WeaviateObject; +import io.weaviate.client6.v1.internal.ObjectBuilder; + +public record WriteWeaviateObject( + @SerializedName("id") String uuid, + @SerializedName("class") String collection, + @SerializedName("tenant") String tenant, + @SerializedName("properties") PropertiesT properties, + @SerializedName("vectors") Vectors vectors, + @SerializedName("creationTimeUnix") Long createdAt, + @SerializedName("lastUpdateTimeUnix") Long lastUpdatedAt, + + Map> references) implements WeaviateObject { + + public static WriteWeaviateObject of( + Function, ObjectBuilder>> fn) { + return fn.apply(new Builder<>()).build(); + } + + public WriteWeaviateObject(Builder builder) { + this( + builder.uuid, + builder.collection, + builder.tenant, + builder.properties, + builder.vectors, + null, // creationTimeUnix is read-only + null, // lastUpdateTimeUnix is read-only + builder.references); + } + + public static class Builder implements ObjectBuilder> { + /** + * The server should be providing default UUIDs, but it does not do that + * during batch inserts and we have to provide our own. + * Rather than make this behaviour special to {@code insertMany}, we are going + * to provide a fallback UUID "globally". + */ + private String uuid = UUID.randomUUID().toString(); + private String collection; + private String tenant; + private PropertiesT properties; + private Vectors vectors; + private Map> references = new HashMap<>(); + + public Builder uuid(String uuid) { + this.uuid = uuid; + return this; + } + + public Builder tenant(String tenant) { + this.tenant = tenant; + return this; + } + + public Builder properties(PropertiesT properties) { + this.properties = properties; + return this; + } + + /** + * Add a reference. Calls to {@link #reference} can be chained + * to add multiple references. + */ + public Builder reference(String property, Reference... references) { + for (var ref : references) { + addReference(property, ref); + } + return this; + } -public record WriteWeaviateObject

( - String collection, - P properties, - Map> references, - ObjectMetadata metadata, - String tenant) { + public Builder references(Map> references) { + this.references = references; + return this; + } + + private void addReference(String property, Reference reference) { + if (!references.containsKey(property)) { + references.put(property, new ArrayList<>()); + } + references.get(property).add(reference); + } - WriteWeaviateObject(WeaviateObject object, String tenant) { - this(object.collection(), object.properties(), object.references(), object.metadata(), tenant); + public Builder vectors(Vectors... vectors) { + if (this.vectors == null) { + this.vectors = vectors.length == 1 ? vectors[0] : new Vectors(vectors); + } else { + this.vectors = this.vectors.withVectors(vectors); + } + return this; + } + + @Override + public WriteWeaviateObject build() { + return new WriteWeaviateObject<>(this); + } } public static enum CustomTypeAdapterFactory implements TypeAdapterFactory { @@ -40,31 +130,28 @@ public TypeAdapter create(Gson gson, TypeToken typeToken) { var rawType = typeToken.getRawType(); if (rawType != WriteWeaviateObject.class || !(type instanceof ParameterizedType parameterized) - || parameterized.getActualTypeArguments().length < 1) { + || parameterized.getActualTypeArguments().length != 1) { return null; } var typeParams = parameterized.getActualTypeArguments(); final var propertiesType = typeParams[0]; - final var propertiesAdapter = gson.getAdapter(TypeToken.get(propertiesType)); - final var metadataAdapter = gson.getAdapter(ObjectMetadata.class); + final var delegate = (TypeAdapter>) gson + .getDelegateAdapter(this, typeToken); + final var propertiesAdapter = (TypeAdapter) gson.getAdapter(TypeToken.get(propertiesType)); final var referencesAdapter = gson.getAdapter(Reference.class); return (TypeAdapter) new TypeAdapter>() { @Override public void write(JsonWriter out, WriteWeaviateObject value) throws IOException { - out.beginObject(); - - out.name("class"); - out.value(value.collection()); + var json = delegate.toJsonTree(value).getAsJsonObject(); + var properties = value.properties() != null + ? propertiesAdapter.toJsonTree(value.properties()).getAsJsonObject() + : new JsonObject(); - out.name("properties"); - if (value.references().isEmpty()) { - ((TypeAdapter) propertiesAdapter).write(out, value.properties()); - } else { - var properties = ((TypeAdapter) propertiesAdapter).toJsonTree(value.properties()).getAsJsonObject(); + if (value.references() != null && !value.references().isEmpty()) { for (var refEntry : value.references().entrySet()) { var beacons = new JsonArray(); for (var reference : refEntry.getValue()) { @@ -73,55 +160,41 @@ public void write(JsonWriter out, WriteWeaviateObject value) throws IOExcepti } properties.add(refEntry.getKey(), beacons); } - Streams.write(properties, out); - } - - // Flatten out metadata fields. - var metadata = metadataAdapter.toJsonTree(value.metadata); - for (var entry : metadata.getAsJsonObject().entrySet()) { - out.name(entry.getKey()); - Streams.write(entry.getValue(), out); } - out.name("tenant"); - out.value(value.tenant()); - - out.endObject(); + json.add("properties", properties); + json.remove("references"); + Streams.write(json, out); } @Override public WriteWeaviateObject read(JsonReader in) throws IOException { - var builder = new WeaviateObject.Builder(); - var metadata = new ObjectMetadata.Builder(); + var json = JsonParser.parseReader(in).getAsJsonObject(); - var object = JsonParser.parseReader(in).getAsJsonObject(); - builder.collection(object.get("class").getAsString()); + var jsonProperties = json.get("properties").getAsJsonObject(); + var objectProperties = new JsonObject(); + var objectReferences = new JsonObject(); - var jsonProperties = object.get("properties").getAsJsonObject(); - var trueProperties = new JsonObject(); for (var property : jsonProperties.entrySet()) { var value = property.getValue(); - if (!value.isJsonArray()) { - trueProperties.add(property.getKey(), value); - continue; - } - var array = value.getAsJsonArray(); - var first = array.get(0); - if (first.isJsonObject() && first.getAsJsonObject().has("beacon")) { - for (var el : array) { - var beacon = referencesAdapter.fromJsonTree(el); - builder.reference(property.getKey(), (Reference) beacon); + + if (value.isJsonArray()) { + var array = value.getAsJsonArray(); + var first = array.get(0); + var isReference = first.isJsonObject() && first.getAsJsonObject().has("beacon"); + + if (isReference) { + objectReferences.add(property.getKey(), value); + continue; } } - } - - builder.properties(propertiesAdapter.fromJsonTree(trueProperties)); - metadata.uuid(object.get("id").getAsString()); - builder.metadata(metadata.build()); + objectProperties.add(property.getKey(), value); + } - var tenant = object.get("tenant"); - return new WriteWeaviateObject<>(builder.build(), tenant != null ? tenant.getAsString() : ""); + json.add("references", objectReferences); + json.add("properties", objectProperties); + return delegate.fromJsonTree(json); } }.nullSafe(); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/pagination/AsyncPage.java b/src/main/java/io/weaviate/client6/v1/api/collections/pagination/AsyncPage.java index 691b8bad6..0e7046fbe 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/pagination/AsyncPage.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/pagination/AsyncPage.java @@ -7,32 +7,31 @@ import java.util.concurrent.CompletableFuture; import java.util.function.BiFunction; -import io.weaviate.client6.v1.api.collections.WeaviateObject; -import io.weaviate.client6.v1.api.collections.query.QueryMetadata; +import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject; -public final class AsyncPage implements Iterable> { +public final class AsyncPage implements Iterable> { private final int pageSize; - private final BiFunction>>> fetch; + private final BiFunction>>> fetch; private final String cursor; - private List> currentPage = new ArrayList<>(); + private List> currentPage = new ArrayList<>(); AsyncPage(String cursor, int pageSize, - BiFunction>>> fetch) { + BiFunction>>> fetch) { this.cursor = cursor; this.pageSize = pageSize; this.fetch = fetch; } AsyncPage(String cursor, int pageSize, - BiFunction>>> fetch, - List> currentPage) { + BiFunction>>> fetch, + List> currentPage) { this(cursor, pageSize, fetch); this.currentPage = Collections.unmodifiableList(currentPage); } - List> items() { + List> items() { return currentPage; } @@ -69,7 +68,7 @@ public CompletableFuture> fetchNextPage() { } @Override - public Iterator> iterator() { + public Iterator> iterator() { return currentPage.iterator(); } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/pagination/AsyncPaginator.java b/src/main/java/io/weaviate/client6/v1/api/collections/pagination/AsyncPaginator.java index 972f07a4f..c82c2df3e 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/pagination/AsyncPaginator.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/pagination/AsyncPaginator.java @@ -5,12 +5,11 @@ import java.util.function.Consumer; import java.util.function.Function; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.query.FetchObjects; import io.weaviate.client6.v1.api.collections.query.Metadata; -import io.weaviate.client6.v1.api.collections.query.QueryMetadata; import io.weaviate.client6.v1.api.collections.query.QueryReference; import io.weaviate.client6.v1.api.collections.query.QueryResponse; +import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject; import io.weaviate.client6.v1.api.collections.query.WeaviateQueryClientAsync; import io.weaviate.client6.v1.internal.ObjectBuilder; @@ -46,25 +45,25 @@ public AsyncPaginator(Builder builder) { this.resultSet = builder.prefetch ? rs.fetchNextPage() : CompletableFuture.completedFuture(rs); } - public CompletableFuture forEach(Consumer> action) { + public CompletableFuture forEach(Consumer> action) { return resultSet .thenCompose(rs -> rs.isEmpty() ? rs.fetchNextPage() : CompletableFuture.completedFuture(rs)) .thenCompose(processEachAndAdvance(action)); } - public CompletableFuture forPage(Consumer>> action) { + public CompletableFuture forPage(Consumer>> action) { return resultSet .thenCompose(rs -> rs.isEmpty() ? rs.fetchNextPage() : CompletableFuture.completedFuture(rs)) .thenCompose(processPageAndAdvance(action)); } private static Function, CompletableFuture> processEachAndAdvance( - Consumer> action) { + Consumer> action) { return processAndAdvanceFunc(rs -> rs.forEach(action)); } private static Function, CompletableFuture> processPageAndAdvance( - Consumer>> action) { + Consumer>> action) { return processAndAdvanceFunc(rs -> action.accept(rs.items())); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/pagination/CursorSpliterator.java b/src/main/java/io/weaviate/client6/v1/api/collections/pagination/CursorSpliterator.java index 3b0335d88..eb45e0402 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/pagination/CursorSpliterator.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/pagination/CursorSpliterator.java @@ -7,27 +7,26 @@ import java.util.function.BiFunction; import java.util.function.Consumer; -import io.weaviate.client6.v1.api.collections.WeaviateObject; -import io.weaviate.client6.v1.api.collections.query.QueryMetadata; +import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject; -public class CursorSpliterator implements Spliterator> { +public class CursorSpliterator implements Spliterator> { private final int pageSize; - private final BiFunction>> fetch; + private final BiFunction>> fetch; // Spliterators do not promise thread-safety, so there's no mechanism // to protect access to its internal state. private String cursor; - private Iterator> currentPage = Collections.emptyIterator(); + private Iterator> currentPage = Collections.emptyIterator(); public CursorSpliterator(String cursor, int pageSize, - BiFunction>> fetch) { + BiFunction>> fetch) { this.cursor = cursor; this.pageSize = pageSize; this.fetch = fetch; } @Override - public boolean tryAdvance(Consumer> action) { + public boolean tryAdvance(Consumer> action) { // Happy path: there are remaining objects in the current page. if (currentPage.hasNext()) { action.accept(currentPage.next()); @@ -54,7 +53,7 @@ public boolean tryAdvance(Consumer> trySplit() { + public Spliterator> trySplit() { // Do not support splitting just now; return null; } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/pagination/Paginator.java b/src/main/java/io/weaviate/client6/v1/api/collections/pagination/Paginator.java index 23d86fb1a..f6893f58b 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/pagination/Paginator.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/pagination/Paginator.java @@ -8,16 +8,15 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.query.FetchObjects; import io.weaviate.client6.v1.api.collections.query.Filter; import io.weaviate.client6.v1.api.collections.query.Metadata; -import io.weaviate.client6.v1.api.collections.query.QueryMetadata; import io.weaviate.client6.v1.api.collections.query.QueryReference; +import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject; import io.weaviate.client6.v1.api.collections.query.WeaviateQueryClient; import io.weaviate.client6.v1.internal.ObjectBuilder; -public class Paginator implements Iterable> { +public class Paginator implements Iterable> { static final int DEFAULT_PAGE_SIZE = 100; private final WeaviateQueryClient query; @@ -26,15 +25,15 @@ public class Paginator implements Iterable> iterator() { + public Iterator> iterator() { return Spliterators.iterator(spliterator()); } - public Stream> stream() { + public Stream> stream() { return StreamSupport.stream(spliterator(), false); } - public Spliterator> spliterator() { + public Spliterator> spliterator() { return new CursorSpliterator(cursor, pageSize, (after, limit) -> { var fn = ObjectBuilder.partial(queryOptions, q -> q.after(after).limit(limit)); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java index 2e440df84..b90c6d748 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java @@ -7,7 +7,6 @@ import io.weaviate.client6.v1.api.WeaviateApiException; import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; @@ -73,7 +72,7 @@ public SingleT fetchObjectById(String uuid, Function Optional> optionalFirst(QueryResponse response) { + protected final

Optional> optionalFirst(QueryResponse

response) { return response == null || response.objects().isEmpty() ? Optional.empty() : Optional.ofNullable(response.objects().get(0)); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryMetadata.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryMetadata.java index 25f8f676e..03896895d 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryMetadata.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryMetadata.java @@ -49,8 +49,12 @@ final Builder uuid(String uuid) { return this; } - final Builder vectors(Vectors vectors) { - this.vectors = vectors; + public Builder vectors(Vectors... vectors) { + if (this.vectors == null) { + this.vectors = vectors.length == 1 ? vectors[0] : new Vectors(vectors); + } else { + this.vectors = this.vectors.withVectors(vectors); + } return this; } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryObjectGrouped.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryObjectGrouped.java index f98014af1..fb6b711d8 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryObjectGrouped.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryObjectGrouped.java @@ -1,7 +1,5 @@ package io.weaviate.client6.v1.api.collections.query; -import io.weaviate.client6.v1.api.collections.WeaviateObject; - public record QueryObjectGrouped( /** Object properties. */ PropertiesT properties, @@ -10,7 +8,7 @@ public record QueryObjectGrouped( /** Name of the group that the object belongs to. */ String belongsToGroup) { - QueryObjectGrouped(WeaviateObject object, + QueryObjectGrouped(ReadWeaviateObject object, String belongsToGroup) { this(object.properties(), object.metadata(), belongsToGroup); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryResponse.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryResponse.java index 283045c9b..af31ceb12 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryResponse.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryResponse.java @@ -7,10 +7,8 @@ import java.util.stream.Stream; import io.weaviate.client6.v1.api.collections.GeoCoordinates; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.PhoneNumber; import io.weaviate.client6.v1.api.collections.Vectors; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.DateUtil; import io.weaviate.client6.v1.internal.grpc.ByteStringUtil; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoProperties; @@ -19,7 +17,7 @@ import io.weaviate.client6.v1.internal.orm.PropertiesBuilder; public record QueryResponse( - List> objects) { + List> objects) { static QueryResponse unmarshal(WeaviateProtoSearchGet.SearchReply reply, CollectionDescriptor collection) { @@ -32,7 +30,7 @@ static QueryResponse unmarshal(WeaviateProtoSearchGet return new QueryResponse<>(objects); } - public static WeaviateObject unmarshalResultObject( + public static ReadWeaviateObject unmarshalResultObject( WeaviateProtoSearchGet.PropertiesResult propertiesResult, WeaviateProtoSearchGet.MetadataResult metadataResult, CollectionDescriptor collection) { @@ -59,11 +57,11 @@ public static WeaviateObject u if (metadataResult.getExplainScorePresent()) { metadata.explainScore(metadataResult.getExplainScore()); } - return new WeaviateObject<>(collection.collectionName(), object.properties(), object.references(), + return new ReadWeaviateObject<>(collection.collectionName(), object.properties(), object.references(), metadata.build()); } - static WeaviateObject unmarshalWithReferences( + static ReadWeaviateObject unmarshalWithReferences( WeaviateProtoSearchGet.PropertiesResult propertiesResult, WeaviateProtoSearchGet.MetadataResult metadataResult, CollectionDescriptor descriptor) { @@ -78,14 +76,14 @@ static WeaviateObject unmarsh // I.e. { "ref": A-1 } , { "ref": B-1 } => { "ref": [A-1, B-1] } var referenceProperties = propertiesResult.getRefPropsList() .stream().reduce( - new HashMap>(), + new HashMap>>(), (map, ref) -> { var refObjects = ref.getPropertiesList().stream() .map(property -> { var reference = unmarshalWithReferences( property, property.getMetadata(), CollectionDescriptor.ofMap(property.getTargetCollection())); - return (Object) new WeaviateObject<>( + return new ReadWeaviateObject<>( reference.collection(), (Object) reference.properties(), reference.references(), @@ -110,9 +108,9 @@ static WeaviateObject unmarsh return left; }); - ObjectMetadata metadata = null; + QueryMetadata metadata = null; if (metadataResult != null) { - var metadataBuilder = new ObjectMetadata.Builder() + var metadataBuilder = new QueryMetadata.Builder() .uuid(metadataResult.getId()); var vectors = new Vectors[metadataResult.getVectorsList().size()]; @@ -141,12 +139,11 @@ static WeaviateObject unmarsh metadata = metadataBuilder.build(); } - var obj = new WeaviateObject.Builder() - .collection(descriptor.collectionName()) - .properties(properties.build()) - .references(referenceProperties) - .metadata(metadata); - return obj.build(); + return new ReadWeaviateObject<>( + descriptor.collectionName(), + properties.build(), + referenceProperties, + metadata); } static void setProperty(String property, WeaviateProtoProperties.Value value, diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/ReadWeaviateObject.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/ReadWeaviateObject.java new file mode 100644 index 000000000..7f8505b79 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/ReadWeaviateObject.java @@ -0,0 +1,26 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.List; +import java.util.Map; + +import io.weaviate.client6.v1.api.collections.Vectors; +import io.weaviate.client6.v1.api.collections.WeaviateObject; + +public record ReadWeaviateObject( + String collection, + PropertiesT properties, + Map>> references, + QueryMetadata metadata) implements WeaviateObject { + + /** Shorthand for accesing objects's UUID from metadata. */ + @Override + public String uuid() { + return metadata.uuid(); + } + + /** Shorthand for accesing objects's vectors from metadata. */ + @Override + public Vectors vectors() { + return metadata.vectors(); + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java index 6e875deda..24c53b753 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java @@ -3,28 +3,27 @@ import java.util.Optional; import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; -public class WeaviateQueryClient +public class WeaviateQueryClient extends - AbstractQueryClient>, QueryResponse, QueryResponseGrouped> { + AbstractQueryClient>, QueryResponse, QueryResponseGrouped> { public WeaviateQueryClient( - CollectionDescriptor collection, + CollectionDescriptor collection, GrpcTransport grpcTransport, CollectionHandleDefaults defaults) { super(collection, grpcTransport, defaults); } /** Copy constructor that sets new defaults. */ - public WeaviateQueryClient(WeaviateQueryClient c, CollectionHandleDefaults defaults) { + public WeaviateQueryClient(WeaviateQueryClient c, CollectionHandleDefaults defaults) { super(c, defaults); } @Override - protected Optional> fetchObjectById(FetchObjectById byId) { + protected Optional> fetchObjectById(FetchObjectById byId) { var request = new QueryRequest(byId, null); var result = this.grpcTransport.performRequest(request, QueryRequest.rpc(collection, defaults)); return optionalFirst(result); @@ -32,13 +31,13 @@ protected Optional> fetchObjectById(Fet } @Override - protected final QueryResponse performRequest(QueryOperator operator) { + protected final QueryResponse performRequest(QueryOperator operator) { var request = new QueryRequest(operator, null); return this.grpcTransport.performRequest(request, QueryRequest.rpc(collection, defaults)); } @Override - protected final QueryResponseGrouped performRequest(QueryOperator operator, GroupBy groupBy) { + protected final QueryResponseGrouped performRequest(QueryOperator operator, GroupBy groupBy) { var request = new QueryRequest(operator, groupBy); return this.grpcTransport.performRequest(request, QueryRequest.grouped(collection, defaults)); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java index 3b5c2e3f6..13bf9ce6d 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java @@ -4,28 +4,27 @@ import java.util.concurrent.CompletableFuture; import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; -public class WeaviateQueryClientAsync +public class WeaviateQueryClientAsync extends - AbstractQueryClient>>, CompletableFuture>, CompletableFuture>> { + AbstractQueryClient>>, CompletableFuture>, CompletableFuture>> { public WeaviateQueryClientAsync( - CollectionDescriptor collection, + CollectionDescriptor collection, GrpcTransport grpcTransport, CollectionHandleDefaults defaults) { super(collection, grpcTransport, defaults); } /** Copy constructor that sets new defaults. */ - public WeaviateQueryClientAsync(WeaviateQueryClientAsync qc, CollectionHandleDefaults defaults) { + public WeaviateQueryClientAsync(WeaviateQueryClientAsync qc, CollectionHandleDefaults defaults) { super(qc, defaults); } @Override - protected CompletableFuture>> fetchObjectById( + protected CompletableFuture>> fetchObjectById( FetchObjectById byId) { var request = new QueryRequest(byId, null); var result = this.grpcTransport.performRequestAsync(request, QueryRequest.rpc(collection, defaults)); @@ -33,13 +32,14 @@ protected CompletableFuture>> } @Override - protected final CompletableFuture> performRequest(QueryOperator operator) { + protected final CompletableFuture> performRequest(QueryOperator operator) { var request = new QueryRequest(operator, null); return this.grpcTransport.performRequestAsync(request, QueryRequest.rpc(collection, defaults)); } @Override - protected final CompletableFuture> performRequest(QueryOperator operator, GroupBy groupBy) { + protected final CompletableFuture> performRequest(QueryOperator operator, + GroupBy groupBy) { var request = new QueryRequest(operator, groupBy); return this.grpcTransport.performRequestAsync(request, QueryRequest.grouped(collection, defaults)); } diff --git a/src/main/java/io/weaviate/client6/v1/internal/json/JSON.java b/src/main/java/io/weaviate/client6/v1/internal/json/JSON.java index 5702250b9..d69e7fdaa 100644 --- a/src/main/java/io/weaviate/client6/v1/internal/json/JSON.java +++ b/src/main/java/io/weaviate/client6/v1/internal/json/JSON.java @@ -22,8 +22,6 @@ public final class JSON { io.weaviate.client6.v1.api.rbac.Permission.CustomTypeAdapterFactory.INSTANCE); gsonBuilder.registerTypeAdapterFactory( io.weaviate.client6.v1.api.rbac.Role.CustomTypeAdapterFactory.INSTANCE); - gsonBuilder.registerTypeAdapterFactory( - io.weaviate.client6.v1.api.collections.WeaviateObject.CustomTypeAdapterFactory.INSTANCE); gsonBuilder.registerTypeAdapterFactory( io.weaviate.client6.v1.api.collections.data.WriteWeaviateObject.CustomTypeAdapterFactory.INSTANCE); gsonBuilder.registerTypeAdapterFactory( 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 9584585bd..1439e9a00 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 @@ -18,7 +18,6 @@ import io.weaviate.client6.v1.api.collections.CollectionConfig; import io.weaviate.client6.v1.api.collections.Encoding; import io.weaviate.client6.v1.api.collections.Generative; -import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Property; import io.weaviate.client6.v1.api.collections.Quantization; import io.weaviate.client6.v1.api.collections.ReferenceProperty; @@ -26,10 +25,10 @@ import io.weaviate.client6.v1.api.collections.Tokenization; import io.weaviate.client6.v1.api.collections.VectorConfig; import io.weaviate.client6.v1.api.collections.Vectors; -import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.data.BatchReference; import io.weaviate.client6.v1.api.collections.data.Reference; import io.weaviate.client6.v1.api.collections.data.ReferenceAddManyResponse; +import io.weaviate.client6.v1.api.collections.data.WriteWeaviateObject; import io.weaviate.client6.v1.api.collections.quantizers.PQ; import io.weaviate.client6.v1.api.collections.rerankers.CohereReranker; import io.weaviate.client6.v1.api.collections.vectorindex.Distance; @@ -414,15 +413,20 @@ public static Object[][] testCases() { "{\"beacon\": \"weaviate://localhost/Doodlebops/id-1\"}", }, - // WeaviateObject.CustomTypeAdapterFactory.INSTANCE + // WriteWeaviateObject.CustomTypeAdapterFactory.INSTANCE { - new TypeToken, Reference, ObjectMetadata>>() { + new TypeToken>>() { }, - new WeaviateObject<>( + new WriteWeaviateObject<>( + "thing-1", "Things", + /* tenant */ null, Map.of("title", "ThingOne"), - Map.of("hasRef", List.of(Reference.uuids("ref-1"))), - ObjectMetadata.of(meta -> meta.uuid("thing-1"))), + /* vectors */ null, + /* creationTimeUnix */ null, + /* lastUpdateTimeUnix */ null, + Map.of("hasRef", List.of(Reference.uuids("ref-1")))), + """ { "class": "Things",