Skip to content

Commit 423f2f5

Browse files
authored
Merge pull request #482 from weaviate/v6-target-vectors
v6: Target vectors
2 parents 8713def + 8eb1ece commit 423f2f5

28 files changed

Lines changed: 2022 additions & 347 deletions

src/it/java/io/weaviate/integration/OIDCSupportITest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public class OIDCSupportITest extends ConcurrentTest {
5555
*/
5656
@Test
5757
public void test_bearerToken() throws Exception {
58-
Assume.assumeTrue("WCS_DUMMY_CI_PW is not set", WCS_DUMMY_CI_PW != null);
58+
Assume.assumeTrue("WCS_DUMMY_CI_PW is not set", WCS_DUMMY_CI_PW != null && !WCS_DUMMY_CI_PW.isBlank());
5959
Assume.assumeTrue("no internet connection", hasInternetConnection());
6060

6161
var passwordAuth = Authentication.resourceOwnerPassword(WCS_DUMMY_CI_USERNAME, WCS_DUMMY_CI_PW, List.of());
@@ -78,7 +78,7 @@ public void test_bearerToken() throws Exception {
7878

7979
@Test
8080
public void test_resourceOwnerPassword() throws Exception {
81-
Assume.assumeTrue("WCS_DUMMY_CI_PW is not set", WCS_DUMMY_CI_PW != null);
81+
Assume.assumeTrue("WCS_DUMMY_CI_PW is not set", WCS_DUMMY_CI_PW != null && !WCS_DUMMY_CI_PW.isBlank());
8282
Assume.assumeTrue("no internet connection", hasInternetConnection());
8383

8484
// Check norwal resource owner password flow works.
@@ -103,7 +103,7 @@ public void test_resourceOwnerPassword() throws Exception {
103103

104104
@Test
105105
public void test_clientCredentials() throws Exception {
106-
Assume.assumeTrue("OKTA_CLIENT_SECRET is not set", OKTA_CLIENT_SECRET != null);
106+
Assume.assumeTrue("OKTA_CLIENT_SECRET is not set", OKTA_CLIENT_SECRET != null && !OKTA_CLIENT_SECRET.isBlank());
107107
Assume.assumeTrue("no internet connection", hasInternetConnection());
108108

109109
// Check norwal client credentials flow works.

src/it/java/io/weaviate/integration/SearchITest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.weaviate.ConcurrentTest;
2020
import io.weaviate.client6.v1.api.WeaviateApiException;
2121
import io.weaviate.client6.v1.api.WeaviateClient;
22+
import io.weaviate.client6.v1.api.collections.ObjectMetadata;
2223
import io.weaviate.client6.v1.api.collections.Property;
2324
import io.weaviate.client6.v1.api.collections.ReferenceProperty;
2425
import io.weaviate.client6.v1.api.collections.VectorConfig;
@@ -31,7 +32,10 @@
3132
import io.weaviate.client6.v1.api.collections.query.QueryMetadata;
3233
import io.weaviate.client6.v1.api.collections.query.QueryResponseGroup;
3334
import io.weaviate.client6.v1.api.collections.query.SortBy;
35+
import io.weaviate.client6.v1.api.collections.query.Target;
3436
import io.weaviate.client6.v1.api.collections.query.Where;
37+
import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw;
38+
import io.weaviate.client6.v1.api.collections.vectorindex.MultiVector;
3539
import io.weaviate.containers.Container;
3640
import io.weaviate.containers.Container.ContainerGroup;
3741
import io.weaviate.containers.Contextionary;
@@ -499,4 +503,50 @@ public void testMetadataAll() throws IOException {
499503
Assertions.assertThat(metadataNearText.distance()).as("distance").isNotNull();
500504
Assertions.assertThat(metadataNearText.certainty()).as("certainty").isNotNull();
501505
}
506+
507+
@Test
508+
public void testNearVector_targetVectors() throws IOException {
509+
// Arrange
510+
var nsThings = ns("Things");
511+
512+
client.collections.create(nsThings,
513+
c -> c.vectorConfig(
514+
VectorConfig.selfProvided("v1d"),
515+
VectorConfig.selfProvided("v2d",
516+
none -> none
517+
.vectorIndex(Hnsw.of(
518+
hnsw -> hnsw.multiVector(MultiVector.of()))))));
519+
520+
var things = client.collections.use(nsThings);
521+
522+
var thing123 = things.data.insert(Map.of(), thing -> thing.vectors(
523+
Vectors.of("v1d", new float[] { 1, 2, 3 }),
524+
Vectors.of("v2d", new float[][] { { 1, 2, 3 }, { 1, 2, 3 } })));
525+
526+
var thing456 = things.data.insertMany(List.of(
527+
WeaviateObject.of(thing -> thing
528+
.metadata(ObjectMetadata.of(
529+
meta -> meta
530+
.vectors(
531+
Vectors.of("v1d", new float[] { 4, 5, 6 }),
532+
Vectors.of("v2d", new float[][] { { 4, 5, 6 }, { 4, 5, 6 } })))))));
533+
Assertions.assertThat(thing456.errors()).as("insert many").isEmpty();
534+
535+
// Act
536+
var got123 = things.query.nearVector(
537+
Target.vector("v1d", new float[] { 1, 2, 3 }),
538+
q -> q.limit(1));
539+
Assertions.assertThat(got123.objects())
540+
.as("search v1d")
541+
.hasSize(1).extracting(WeaviateObject::uuid)
542+
.containsExactly(thing123.uuid());
543+
544+
var got456 = things.query.nearVector(
545+
Target.vector("v2d", new float[][] { { 4, 5, 6 }, { 4, 5, 6 } }),
546+
q -> q.limit(1));
547+
Assertions.assertThat(got456.objects())
548+
.as("search v2d")
549+
.hasSize(1).extracting(WeaviateObject::uuid)
550+
.containsExactly(thing456.uuids().get(0));
551+
}
502552
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package io.weaviate.client6.v1.api.collections;
2+
3+
import java.io.IOException;
4+
import java.util.EnumMap;
5+
import java.util.Map;
6+
import java.util.function.Function;
7+
8+
import com.google.gson.Gson;
9+
import com.google.gson.JsonParser;
10+
import com.google.gson.TypeAdapter;
11+
import com.google.gson.TypeAdapterFactory;
12+
import com.google.gson.reflect.TypeToken;
13+
import com.google.gson.stream.JsonReader;
14+
import com.google.gson.stream.JsonWriter;
15+
16+
import io.weaviate.client6.v1.api.collections.encoding.MuveraEncoding;
17+
import io.weaviate.client6.v1.internal.ObjectBuilder;
18+
import io.weaviate.client6.v1.internal.json.JsonEnum;
19+
20+
public interface Encoding {
21+
22+
enum Kind implements JsonEnum<Kind> {
23+
MUVERA("muvera");
24+
25+
private static final Map<String, Kind> jsonValueMap = JsonEnum.collectNames(Kind.values());
26+
private final String jsonValue;
27+
28+
private Kind(String jsonValue) {
29+
this.jsonValue = jsonValue;
30+
}
31+
32+
@Override
33+
public String jsonValue() {
34+
return this.jsonValue;
35+
}
36+
37+
public static Kind valueOfJson(String jsonValue) {
38+
return JsonEnum.valueOfJson(jsonValue, jsonValueMap, Kind.class);
39+
}
40+
}
41+
42+
Kind _kind();
43+
44+
Object _self();
45+
46+
public static Encoding muvera() {
47+
return MuveraEncoding.of();
48+
}
49+
50+
public static Encoding muvera(Function<MuveraEncoding.Builder, ObjectBuilder<MuveraEncoding>> fn) {
51+
return MuveraEncoding.of(fn);
52+
}
53+
54+
public enum CustomTypeAdapterFactory implements TypeAdapterFactory {
55+
INSTANCE;
56+
57+
private static final EnumMap<Encoding.Kind, TypeAdapter<? extends Encoding>> delegateAdapters = new EnumMap<>(
58+
Encoding.Kind.class);
59+
60+
private final void addAdapter(Gson gson, Encoding.Kind kind, Class<? extends Encoding> cls) {
61+
delegateAdapters.put(kind,
62+
(TypeAdapter<? extends Encoding>) gson.getDelegateAdapter(this, TypeToken.get(cls)));
63+
}
64+
65+
private final void init(Gson gson) {
66+
addAdapter(gson, Encoding.Kind.MUVERA, MuveraEncoding.class);
67+
}
68+
69+
@SuppressWarnings("unchecked")
70+
@Override
71+
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
72+
final var rawType = type.getRawType();
73+
if (!Encoding.class.isAssignableFrom(rawType)) {
74+
return null;
75+
}
76+
77+
if (delegateAdapters.isEmpty()) {
78+
init(gson);
79+
}
80+
81+
return (TypeAdapter<T>) new TypeAdapter<Encoding>() {
82+
83+
@Override
84+
public void write(JsonWriter out, Encoding value) throws IOException {
85+
TypeAdapter<T> adapter = (TypeAdapter<T>) delegateAdapters.get(value._kind());
86+
adapter.write(out, (T) value._self());
87+
}
88+
89+
@Override
90+
public Encoding read(JsonReader in) throws IOException {
91+
var encodingObject = JsonParser.parseReader(in).getAsJsonObject();
92+
var encodingName = encodingObject.keySet().iterator().next();
93+
94+
Encoding.Kind kind;
95+
try {
96+
kind = Encoding.Kind.valueOfJson(encodingName);
97+
} catch (IllegalArgumentException e) {
98+
return null;
99+
}
100+
101+
var adapter = delegateAdapters.get(kind);
102+
var concreteEncoding = encodingObject.get(encodingName).getAsJsonObject();
103+
return adapter.fromJsonTree(concreteEncoding);
104+
}
105+
}.nullSafe();
106+
}
107+
}
108+
}

src/main/java/io/weaviate/client6/v1/api/collections/ObjectMetadata.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ public ObjectMetadata(Builder builder) {
1717
this(builder.uuid, builder.vectors, null, null);
1818
}
1919

20+
public static ObjectMetadata of() {
21+
return of(ObjectBuilder.identity());
22+
}
23+
2024
public static ObjectMetadata of(Function<Builder, ObjectBuilder<ObjectMetadata>> fn) {
2125
return fn.apply(new Builder()).build();
2226
}
2327

2428
public static class Builder implements ObjectBuilder<ObjectMetadata> {
25-
private String uuid;
29+
private String uuid = UUID.randomUUID().toString();
2630
private Vectors vectors;
2731

2832
/** Assign a custom UUID for the object. */

src/main/java/io/weaviate/client6/v1/api/collections/Quantization.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
148148
@Override
149149
public void write(JsonWriter out, Quantization value) throws IOException {
150150
if (value._kind() == Quantization.Kind.UNCOMPRESSED) {
151-
// out.name(value._kind().jsonValue());
152151
out.value(true);
153152
return;
154153
}

src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import io.weaviate.client6.v1.api.collections.query.NearThermal;
1616
import io.weaviate.client6.v1.api.collections.query.NearVector;
1717
import io.weaviate.client6.v1.api.collections.query.NearVideo;
18+
import io.weaviate.client6.v1.api.collections.query.Target;
1819
import io.weaviate.client6.v1.internal.ObjectBuilder;
1920
import io.weaviate.client6.v1.internal.grpc.GrpcTransport;
2021
import io.weaviate.client6.v1.internal.orm.CollectionDescriptor;
@@ -197,7 +198,7 @@ public GroupedResponseT hybrid(Hybrid filter, Function<Aggregation.Builder, Obje
197198
* @see AggregateResponse
198199
*/
199200
public ResponseT nearVector(float[] vector, Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn) {
200-
return nearVector(NearVector.of(vector), fn);
201+
return nearVector(NearVector.of(Target.vector(vector)), fn);
201202
}
202203

203204
/**
@@ -214,7 +215,7 @@ public ResponseT nearVector(float[] vector, Function<Aggregation.Builder, Object
214215
*/
215216
public ResponseT nearVector(float[] vector, Function<NearVector.Builder, ObjectBuilder<NearVector>> nv,
216217
Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn) {
217-
return nearVector(NearVector.of(vector, nv), fn);
218+
return nearVector(NearVector.of(Target.vector(vector), nv), fn);
218219
}
219220

220221
/**
@@ -248,7 +249,7 @@ public ResponseT nearVector(NearVector filter, Function<Aggregation.Builder, Obj
248249
*/
249250
public GroupedResponseT nearVector(float[] vector, Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn,
250251
GroupBy groupBy) {
251-
return nearVector(NearVector.of(vector), fn, groupBy);
252+
return nearVector(NearVector.of(Target.vector(vector)), fn, groupBy);
252253
}
253254

254255
/**
@@ -268,7 +269,7 @@ public GroupedResponseT nearVector(float[] vector, Function<Aggregation.Builder,
268269
*/
269270
public GroupedResponseT nearVector(float[] vector, Function<NearVector.Builder, ObjectBuilder<NearVector>> nv,
270271
Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn, GroupBy groupBy) {
271-
return nearVector(NearVector.of(vector, nv), fn, groupBy);
272+
return nearVector(NearVector.of(Target.vector(vector), nv), fn, groupBy);
272273
}
273274

274275
/**
@@ -426,7 +427,7 @@ public ResponseT nearText(String text, Function<Aggregation.Builder, ObjectBuild
426427
* @see AggregateResponse
427428
*/
428429
public ResponseT nearText(List<String> concepts, Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn) {
429-
return nearText(NearText.of(concepts), fn);
430+
return nearText(NearText.of(Target.text(concepts)), fn);
430431
}
431432

432433
/**
@@ -443,7 +444,7 @@ public ResponseT nearText(List<String> concepts, Function<Aggregation.Builder, O
443444
*/
444445
public ResponseT nearText(String text, Function<NearText.Builder, ObjectBuilder<NearText>> nt,
445446
Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn) {
446-
return nearText(NearText.of(text, nt), fn);
447+
return nearText(NearText.of(Target.text(List.of(text)), nt), fn);
447448
}
448449

449450
/**
@@ -460,7 +461,7 @@ public ResponseT nearText(String text, Function<NearText.Builder, ObjectBuilder<
460461
*/
461462
public ResponseT nearText(List<String> concepts, Function<NearText.Builder, ObjectBuilder<NearText>> nt,
462463
Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn) {
463-
return nearText(NearText.of(concepts, nt), fn);
464+
return nearText(NearText.of(Target.text(concepts), nt), fn);
464465
}
465466

466467
/**
@@ -512,7 +513,7 @@ public GroupedResponseT nearText(String text, Function<Aggregation.Builder, Obje
512513
*/
513514
public GroupedResponseT nearText(List<String> concepts, Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn,
514515
GroupBy groupBy) {
515-
return nearText(NearText.of(concepts), fn, groupBy);
516+
return nearText(NearText.of(Target.text(concepts)), fn, groupBy);
516517
}
517518

518519
/**
@@ -552,7 +553,7 @@ public GroupedResponseT nearText(String text, Function<NearText.Builder, ObjectB
552553
*/
553554
public GroupedResponseT nearText(List<String> concepts, Function<NearText.Builder, ObjectBuilder<NearText>> nt,
554555
Function<Aggregation.Builder, ObjectBuilder<Aggregation>> fn, GroupBy groupBy) {
555-
return nearText(NearText.of(concepts, nt), fn, groupBy);
556+
return nearText(NearText.of(Target.text(concepts), nt), fn, groupBy);
556557
}
557558

558559
/**

src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults;
1111
import io.weaviate.client6.v1.api.collections.ObjectMetadata;
1212
import io.weaviate.client6.v1.api.collections.WeaviateObject;
13-
import io.weaviate.client6.v1.internal.Debug;
1413
import io.weaviate.client6.v1.internal.MapUtil;
1514
import io.weaviate.client6.v1.internal.grpc.ByteStringUtil;
1615
import io.weaviate.client6.v1.internal.grpc.Rpc;
@@ -32,9 +31,7 @@ public InsertManyRequest(WeaviateObject<T, Reference, ObjectMetadata>... objects
3231
public static final <T> InsertManyRequest<T> of(T... properties) {
3332
var objects = Arrays.stream(properties)
3433
.map(p -> WeaviateObject.<T, Reference, ObjectMetadata>of(
35-
obj -> obj
36-
.properties(p)
37-
.metadata(ObjectMetadata.of(m -> m.uuid(UUID.randomUUID())))))
34+
obj -> obj.properties(p).metadata(ObjectMetadata.of())))
3835
.toList();
3936
return new InsertManyRequest<T>(objects);
4037
}
@@ -102,9 +99,7 @@ public static <T> void buildObject(WeaviateProtoBatch.BatchObject.Builder object
10299

103100
var metadata = insert.metadata();
104101
if (metadata != null) {
105-
if (metadata.uuid() != null) {
106-
object.setUuid(metadata.uuid());
107-
}
102+
object.setUuid(metadata.uuid());
108103

109104
if (metadata.vectors() != null) {
110105
var vectors = metadata.vectors().asMap()
@@ -157,13 +152,15 @@ public static <T> void buildObject(WeaviateProtoBatch.BatchObject.Builder object
157152
}
158153
});
159154

160-
var nonRef = marshalStruct(collection.propertiesReader(insert.properties()).readProperties());
161-
object.setProperties(WeaviateProtoBatch.BatchObject.Properties.newBuilder()
162-
.setNonRefProperties(nonRef)
155+
var properties = WeaviateProtoBatch.BatchObject.Properties.newBuilder()
163156
.addAllSingleTargetRefProps(singleRef)
164-
.addAllMultiTargetRefProps(multiRef));
157+
.addAllMultiTargetRefProps(multiRef);
165158

166-
Debug.printProto(object);
159+
if (insert.properties() != null) {
160+
var nonRef = marshalStruct(collection.propertiesReader(insert.properties()).readProperties());
161+
properties.setNonRefProperties(nonRef);
162+
}
163+
object.setProperties(properties);
167164
}
168165

169166
@SuppressWarnings("unchecked")

0 commit comments

Comments
 (0)