Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions src/it/java/io/weaviate/integration/DataITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
import io.weaviate.client6.v1.api.collections.Property;
import io.weaviate.client6.v1.api.collections.Vectors;
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.Metadata;
import io.weaviate.client6.v1.api.collections.query.QueryReference;
import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw;
import io.weaviate.client6.v1.api.collections.vectorizers.NoneVectorizer;
import io.weaviate.containers.Container;
Expand Down Expand Up @@ -101,4 +103,76 @@ private static void createTestCollections() throws IOException {
Property.reference("hasAwards", awardsGrammy, awardsOscar))
.vectors(named -> named.vector(VECTOR_INDEX, Hnsw.of(new NoneVectorizer()))));
}

@Test
public void testReferences_AddReplaceDelete() throws IOException {
// Arrange
var nsPersons = ns("Person");

client.collections.create(nsPersons,
collection -> collection
.properties(Property.text("name"))
.references(Property.reference("hasFriend", nsPersons)));

var persons = client.collections.use(nsPersons);
var john = persons.data.insert(Map.of("name", "john"));
var albie = persons.data.insert(Map.of("name", "albie"));

// Act: add reference
persons.data.referenceAdd(
john.metadata().uuid(),
"hasFriend",
Reference.object(albie));

// Assert
var johnWithFriends = persons.query.byId(john.metadata().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))
.hasSize(1)
.first().extracting(WeaviateObject::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(),
"hasFriend",
Reference.object(barbara));

johnWithFriends = persons.query.byId(john.metadata().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))
.hasSize(1)
.first().extracting(WeaviateObject::properties, InstanceOfAssertFactories.MAP)
.returns("barbara", friend -> friend.get("name"));

// Act: delete reference
persons.data.referenceDelete(
john.metadata().uuid(),
"hasFriend",
Reference.object(barbara));

// Assert
johnWithFriends = persons.query.byId(john.metadata().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))
.isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ public static Reference uuids(String... uuids) {
return new Reference(null, Arrays.asList(uuids));
}

/** Create references to {@link WeaviateObject}. */
/** Create references to single {@link WeaviateObject}. */
public static Reference object(WeaviateObject<?, ?, ?> object) {
return new Reference(object.collection(), object.metadata().uuid());
}

/** Create references to multiple {@link WeaviateObject}. */
public static Reference[] objects(WeaviateObject<?, ?, ?>... objects) {
return Arrays.stream(objects)
.map(o -> new Reference(o.collection(), o.metadata().uuid()))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.weaviate.client6.v1.api.collections.data;

import java.util.Collections;

import org.apache.hc.core5.http.HttpStatus;

import io.weaviate.client6.v1.internal.json.JSON;
import io.weaviate.client6.v1.internal.orm.CollectionDescriptor;
import io.weaviate.client6.v1.internal.rest.Endpoint;

public record ReferenceAddRequest(String fromUuid, String fromProperty, Reference reference) {

public static final Endpoint<ReferenceAddRequest, Void> endpoint(
CollectionDescriptor<?> descriptor) {
return Endpoint.of(
request -> "POST",
request -> "/objects/" + descriptor.name() + "/" + request.fromUuid + "/references/" + request.fromProperty,
(gson, request) -> JSON.serialize(request.reference),
request -> Collections.emptyMap(),
code -> code != HttpStatus.SC_SUCCESS,
(gson, response) -> null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.weaviate.client6.v1.api.collections.data;

import java.util.Collections;

import org.apache.hc.core5.http.HttpStatus;

import io.weaviate.client6.v1.internal.json.JSON;
import io.weaviate.client6.v1.internal.orm.CollectionDescriptor;
import io.weaviate.client6.v1.internal.rest.Endpoint;

public record ReferenceDeleteRequest(String fromUuid, String fromProperty, Reference reference) {

public static final Endpoint<ReferenceDeleteRequest, Void> endpoint(
CollectionDescriptor<?> descriptor) {
return Endpoint.of(
request -> "DELETE",
request -> "/objects/" + descriptor.name() + "/" + request.fromUuid + "/references/" + request.fromProperty,
(gson, request) -> JSON.serialize(request.reference),
request -> Collections.emptyMap(),
code -> code != HttpStatus.SC_SUCCESS,
(gson, response) -> null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.weaviate.client6.v1.api.collections.data;

import java.util.Collections;
import java.util.List;

import org.apache.hc.core5.http.HttpStatus;

import io.weaviate.client6.v1.internal.json.JSON;
import io.weaviate.client6.v1.internal.orm.CollectionDescriptor;
import io.weaviate.client6.v1.internal.rest.Endpoint;

public record ReferenceReplaceRequest(String fromUuid, String fromProperty, Reference reference) {

public static final Endpoint<ReferenceReplaceRequest, Void> endpoint(
CollectionDescriptor<?> descriptor) {
return Endpoint.of(
request -> "PUT",
request -> "/objects/" + descriptor.name() + "/" + request.fromUuid + "/references/" + request.fromProperty,
(gson, request) -> JSON.serialize(List.of(request.reference)),
request -> Collections.emptyMap(),
code -> code != HttpStatus.SC_SUCCESS,
(gson, response) -> null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,28 @@ public void delete(String uuid) throws IOException {
this.restTransport.performRequest(new DeleteObjectRequest(collectionDescriptor.name(), uuid),
DeleteObjectRequest._ENDPOINT);
}

public void referenceAdd(String fromUuid, String fromProperty, Reference reference) throws IOException {
for (var uuid : reference.uuids()) {
var singleRef = new Reference(reference.collection(), uuid);
this.restTransport.performRequest(new ReferenceAddRequest(fromUuid, fromProperty, singleRef),
ReferenceAddRequest.endpoint(collectionDescriptor));
}
}

public void referenceDelete(String fromUuid, String fromProperty, Reference reference) throws IOException {
for (var uuid : reference.uuids()) {
var singleRef = new Reference(reference.collection(), uuid);
this.restTransport.performRequest(new ReferenceDeleteRequest(fromUuid, fromProperty, singleRef),
ReferenceDeleteRequest.endpoint(collectionDescriptor));
}
}

public void referenceReplace(String fromUuid, String fromProperty, Reference reference) throws IOException {
for (var uuid : reference.uuids()) {
var singleRef = new Reference(reference.collection(), uuid);
this.restTransport.performRequest(new ReferenceReplaceRequest(fromUuid, fromProperty, singleRef),
ReferenceReplaceRequest.endpoint(collectionDescriptor));
}
}
}