Skip to content

Commit 6befa30

Browse files
authored
Merge pull request #508 from weaviate/v6-dx
v6: Bugfixes and minor improvements
2 parents e410c07 + 045af07 commit 6befa30

30 files changed

+438
-47
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@
410410
<executions>
411411
<execution>
412412
<id>sign-artifacts</id>
413-
<phase>verify</phase>
413+
<phase>deploy</phase>
414414
<goals>
415415
<goal>sign</goal>
416416
</goals>

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import io.weaviate.client6.v1.api.collections.DataType;
1414
import io.weaviate.client6.v1.api.collections.InvertedIndex;
1515
import io.weaviate.client6.v1.api.collections.Property;
16+
import io.weaviate.client6.v1.api.collections.Quantization;
1617
import io.weaviate.client6.v1.api.collections.ReferenceProperty;
1718
import io.weaviate.client6.v1.api.collections.Replication;
1819
import io.weaviate.client6.v1.api.collections.VectorConfig;
@@ -194,7 +195,7 @@ public void testInvalidCollectionName() throws IOException {
194195
}
195196

196197
@Test
197-
public void testNestedProperties() throws IOException, Exception {
198+
public void testNestedProperties() throws IOException {
198199
var nsBuildings = ns("Buildings");
199200

200201
client.collections.create(
@@ -227,4 +228,27 @@ public void testNestedProperties() throws IOException, Exception {
227228
.extracting(Property::dataTypes).extracting(types -> types.get(0))
228229
.containsExactly(DataType.INT, DataType.NUMBER);
229230
}
231+
232+
@Test
233+
public void test_updateQuantization() throws IOException {
234+
// Arrange
235+
var nsThings = ns("Things");
236+
237+
var things = client.collections.create(nsThings,
238+
c -> c.vectorConfig(VectorConfig.selfProvided(
239+
self -> self.quantization(Quantization.uncompressed()))));
240+
241+
// Act
242+
things.config.update(
243+
c -> c.vectorConfig(VectorConfig.selfProvided(
244+
self -> self.quantization(Quantization.bq()))));
245+
246+
// Assert
247+
var config = things.config.get();
248+
Assertions.assertThat(config).get()
249+
.extracting(CollectionConfig::vectors)
250+
.extracting("default", InstanceOfAssertFactories.type(VectorConfig.class))
251+
.extracting(VectorConfig::quantization)
252+
.returns(Quantization.Kind.BQ, Quantization::_kind);
253+
}
230254
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
import io.weaviate.client6.v1.api.collections.data.BatchReference;
2525
import io.weaviate.client6.v1.api.collections.data.DeleteManyResponse;
2626
import io.weaviate.client6.v1.api.collections.data.Reference;
27+
import io.weaviate.client6.v1.api.collections.query.Filter;
2728
import io.weaviate.client6.v1.api.collections.query.Metadata;
2829
import io.weaviate.client6.v1.api.collections.query.Metadata.MetadataField;
2930
import io.weaviate.client6.v1.api.collections.query.QueryMetadata;
3031
import io.weaviate.client6.v1.api.collections.query.QueryReference;
31-
import io.weaviate.client6.v1.api.collections.query.Filter;
3232
import io.weaviate.containers.Container;
3333

3434
public class DataITest extends ConcurrentTest {

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

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
import io.weaviate.ConcurrentTest;
2222
import io.weaviate.client6.v1.api.WeaviateApiException;
2323
import io.weaviate.client6.v1.api.WeaviateClient;
24+
import io.weaviate.client6.v1.api.collections.Generative;
2425
import io.weaviate.client6.v1.api.collections.ObjectMetadata;
2526
import io.weaviate.client6.v1.api.collections.Property;
2627
import io.weaviate.client6.v1.api.collections.ReferenceProperty;
28+
import io.weaviate.client6.v1.api.collections.Reranker;
2729
import io.weaviate.client6.v1.api.collections.VectorConfig;
2830
import io.weaviate.client6.v1.api.collections.Vectors;
2931
import io.weaviate.client6.v1.api.collections.WeaviateMetadata;
@@ -37,8 +39,10 @@
3739
import io.weaviate.client6.v1.api.collections.query.Metadata;
3840
import io.weaviate.client6.v1.api.collections.query.QueryMetadata;
3941
import io.weaviate.client6.v1.api.collections.query.QueryResponseGroup;
42+
import io.weaviate.client6.v1.api.collections.query.Rerank;
4043
import io.weaviate.client6.v1.api.collections.query.SortBy;
4144
import io.weaviate.client6.v1.api.collections.query.Target;
45+
import io.weaviate.client6.v1.api.collections.rerankers.DummyReranker;
4246
import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw;
4347
import io.weaviate.client6.v1.api.collections.vectorindex.MultiVector;
4448
import io.weaviate.containers.Container;
@@ -52,7 +56,7 @@ public class SearchITest extends ConcurrentTest {
5256
Weaviate.custom()
5357
.withModel2VecUrl(Model2Vec.URL)
5458
.withImageInference(Img2VecNeural.URL, Img2VecNeural.MODULE)
55-
.addModules("generative-dummy")
59+
.addModules(Generative.Kind.DUMMY.jsonValue(), Reranker.Kind.DUMMY.jsonValue())
5660
.build(),
5761
Container.IMG2VEC_NEURAL,
5862
Container.MODEL2VEC);
@@ -741,7 +745,7 @@ public void teset_filterPropertyLength() throws IOException {
741745
// Assertions
742746
Assertions.assertThat(got.objects()).hasSize(2);
743747
}
744-
748+
745749
/**
746750
* Ensure the client respects server's configuration for max gRPC size:
747751
* we create a server with 1-byte message size and try to send a large payload
@@ -768,4 +772,30 @@ public void test_maxGrpcMessageSize() throws Exception {
768772
}).isInstanceOf(io.grpc.StatusRuntimeException.class);
769773
}
770774
}
775+
776+
@Test
777+
public void test_rerankQueries() throws IOException {
778+
// Arrange
779+
var nsThigns = ns("Things");
780+
781+
var things = client.collections.create(nsThigns,
782+
c -> c
783+
.properties(Property.text("title"), Property.integer("price"))
784+
.vectorConfig(VectorConfig.text2vecModel2Vec(
785+
t2v -> t2v.sourceProperties("title", "price")))
786+
.rerankerModules(new DummyReranker()));
787+
788+
things.data.insertMany(
789+
Map.of("title", "Ergonomic chair", "price", 269),
790+
Map.of("title", "Height-adjustable desk", "price", 349));
791+
792+
// Act
793+
var got = things.query.nearText(
794+
"office supplies",
795+
nt -> nt.rerank(Rerank.by("price",
796+
rank -> rank.query("cheaper first"))));
797+
798+
// Assert: ranking not important really, just that the request was valid.
799+
Assertions.assertThat(got.objects()).hasSize(2);
800+
}
771801
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,19 +276,23 @@ public void write(JsonWriter out, CollectionConfig value) throws IOException {
276276
// Reranker and Generative module configs belong to the "moduleConfig".
277277
var rerankerModules = jsonObject.remove("rerankerModules").getAsJsonArray();
278278
var generativeModule = jsonObject.remove("generativeModule");
279-
if (!rerankerModules.isEmpty() || !generativeModule.isJsonNull()) {
280-
var modules = new JsonObject();
281279

280+
var modules = new JsonObject();
281+
if (!rerankerModules.isEmpty()) {
282282
// Copy configuration for each reranker module.
283283
rerankerModules.forEach(reranker -> {
284284
reranker.getAsJsonObject().entrySet()
285285
.stream().forEach(entry -> modules.add(entry.getKey(), entry.getValue()));
286286
});
287+
}
287288

289+
if (!generativeModule.isJsonNull()) {
288290
// Copy configuration for each generative module.
289291
generativeModule.getAsJsonObject().entrySet()
290292
.stream().forEach(entry -> modules.add(entry.getKey(), entry.getValue()));
293+
}
291294

295+
if (!modules.isEmpty()) {
292296
jsonObject.add("moduleConfig", modules);
293297
}
294298

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

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
import io.weaviate.client6.v1.api.collections.quantizers.SQ;
2020
import io.weaviate.client6.v1.api.collections.quantizers.Uncompressed;
2121
import io.weaviate.client6.v1.internal.ObjectBuilder;
22+
import io.weaviate.client6.v1.internal.TaggedUnion;
2223
import io.weaviate.client6.v1.internal.json.JsonEnum;
2324

24-
public interface Quantization {
25+
public interface Quantization extends TaggedUnion<Quantization.Kind, Object> {
2526

2627
public enum Kind implements JsonEnum<Kind> {
2728
UNCOMPRESSED("skipDefaultQuantization"),
@@ -112,6 +113,46 @@ public static Quantization rq(Function<RQ.Builder, ObjectBuilder<RQ>> fn) {
112113
return RQ.of(fn);
113114
}
114115

116+
default BQ asBQ() {
117+
return _as(Quantization.Kind.BQ);
118+
}
119+
120+
default RQ asRQ() {
121+
return _as(Quantization.Kind.RQ);
122+
}
123+
124+
default PQ asPQ() {
125+
return _as(Quantization.Kind.PQ);
126+
}
127+
128+
default SQ asSQ() {
129+
return _as(Quantization.Kind.SQ);
130+
}
131+
132+
default Uncompressed asUncompressed() {
133+
return _as(Quantization.Kind.UNCOMPRESSED);
134+
}
135+
136+
default boolean isBQ() {
137+
return _is(Quantization.Kind.BQ);
138+
}
139+
140+
default boolean isRQ() {
141+
return _is(Quantization.Kind.RQ);
142+
}
143+
144+
default boolean isPQ() {
145+
return _is(Quantization.Kind.PQ);
146+
}
147+
148+
default boolean isSQ() {
149+
return _is(Quantization.Kind.SQ);
150+
}
151+
152+
default boolean isUncompressed() {
153+
return _is(Quantization.Kind.UNCOMPRESSED);
154+
}
155+
115156
public static enum CustomTypeAdapterFactory implements TypeAdapterFactory {
116157
INSTANCE;
117158

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.google.gson.stream.JsonWriter;
1515

1616
import io.weaviate.client6.v1.api.collections.rerankers.CohereReranker;
17+
import io.weaviate.client6.v1.api.collections.rerankers.DummyReranker;
1718
import io.weaviate.client6.v1.api.collections.rerankers.JinaAiReranker;
1819
import io.weaviate.client6.v1.api.collections.rerankers.NvidiaReranker;
1920
import io.weaviate.client6.v1.api.collections.rerankers.TransformersReranker;
@@ -24,6 +25,7 @@
2425

2526
public interface Reranker extends TaggedUnion<Reranker.Kind, Object> {
2627
public enum Kind implements JsonEnum<Kind> {
28+
DUMMY("reranker-dummy"),
2729
JINAAI("reranker-jinaai"),
2830
VOYAGEAI("reranker-voyageai"),
2931
NVIDIA("reranker-nvidia"),
@@ -120,6 +122,11 @@ private final void addAdapter(Gson gson, Reranker.Kind kind, Class<? extends Rer
120122

121123
private final void init(Gson gson) {
122124
addAdapter(gson, Reranker.Kind.COHERE, CohereReranker.class);
125+
addAdapter(gson, Reranker.Kind.JINAAI, JinaAiReranker.class);
126+
addAdapter(gson, Reranker.Kind.NVIDIA, NvidiaReranker.class);
127+
addAdapter(gson, Reranker.Kind.TRANSFORMERS, TransformersReranker.class);
128+
addAdapter(gson, Reranker.Kind.VOYAGEAI, VoyageAiReranker.class);
129+
addAdapter(gson, Reranker.Kind.DUMMY, DummyReranker.class);
123130
}
124131

125132
@SuppressWarnings("unchecked")

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

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,15 +1606,18 @@ public VectorConfig read(JsonReader in) throws IOException {
16061606
var vectorIndexConfig = jsonObject.get("vectorIndexConfig").getAsJsonObject();
16071607

16081608
String quantizationKind = null;
1609-
if (vectorIndexConfig.has(Quantization.Kind.BQ.jsonValue())) {
1610-
quantizationKind = Quantization.Kind.BQ.jsonValue();
1611-
} else if (vectorIndexConfig.has(Quantization.Kind.PQ.jsonValue())) {
1612-
quantizationKind = Quantization.Kind.PQ.jsonValue();
1613-
} else if (vectorIndexConfig.has(Quantization.Kind.SQ.jsonValue())) {
1614-
quantizationKind = Quantization.Kind.SQ.jsonValue();
1615-
} else if (vectorIndexConfig.has(Quantization.Kind.RQ.jsonValue())) {
1616-
quantizationKind = Quantization.Kind.RQ.jsonValue();
1617-
} else {
1609+
for (var kind : new String[] {
1610+
Quantization.Kind.BQ.jsonValue(),
1611+
Quantization.Kind.PQ.jsonValue(),
1612+
Quantization.Kind.SQ.jsonValue(),
1613+
Quantization.Kind.RQ.jsonValue() }) {
1614+
if (vectorIndexConfig.has(kind)
1615+
&& vectorIndexConfig.get(kind).getAsJsonObject().get("enabled").getAsBoolean()) {
1616+
quantizationKind = kind;
1617+
}
1618+
}
1619+
if (quantizationKind == null && vectorIndexConfig.has(Quantization.Kind.UNCOMPRESSED.jsonValue())
1620+
&& vectorIndexConfig.get(Quantization.Kind.UNCOMPRESSED.jsonValue()).getAsBoolean()) {
16181621
quantizationKind = Quantization.Kind.UNCOMPRESSED.jsonValue();
16191622
}
16201623

@@ -1649,7 +1652,7 @@ public VectorConfig read(JsonReader in) throws IOException {
16491652
// Each individual vectorizer has a `Quantization quantization` field.
16501653
// We need to specify the kind in order for
16511654
// Quantization.CustomTypeAdapterFactory to be able to find the right adapter.
1652-
if (vectorIndexConfig.has(quantizationKind)) {
1655+
if (quantizationKind != null && vectorIndexConfig.has(quantizationKind)) {
16531656
JsonObject quantization = new JsonObject();
16541657
quantization.add(quantizationKind, vectorIndexConfig.get(quantizationKind));
16551658
concreteVectorizer.add("quantization", quantization);

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
import java.util.List;
66
import java.util.function.Function;
77

8+
import io.weaviate.client6.v1.api.collections.query.Filter;
89
import io.weaviate.client6.v1.internal.ObjectBuilder;
910
import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoAggregate;
11+
import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase;
1012

1113
public record Aggregation(
1214
AggregateObjectFilter filter,
15+
Filter whereFilter,
1316
Integer objectLimit,
1417
boolean includeTotalCount,
1518
List<PropertyAggregation> returnMetrics) {
@@ -29,6 +32,7 @@ public static Aggregation of(AggregateObjectFilter objectFilter, Function<Builde
2932
public Aggregation(Builder builder) {
3033
this(
3134
builder.objectFilter,
35+
builder.whereFilter,
3236
builder.objectLimit,
3337
builder.includeTotalCount,
3438
builder.metrics);
@@ -41,6 +45,7 @@ public Builder(AggregateObjectFilter objectFilter) {
4145
this.objectFilter = objectFilter;
4246
}
4347

48+
private Filter whereFilter;
4449
private List<PropertyAggregation> metrics = new ArrayList<>();
4550
private Integer objectLimit;
4651
private boolean includeTotalCount = false;
@@ -55,6 +60,24 @@ public final Builder includeTotalCount(boolean include) {
5560
return this;
5661
}
5762

63+
/**
64+
* Filter result set using traditional filtering operators: {@code eq},
65+
* {@code gte}, {@code like}, etc.
66+
* Subsequent calls to {@link #filter} aggregate with an AND operator.
67+
*/
68+
public final Builder filters(Filter filter) {
69+
this.whereFilter = this.whereFilter == null
70+
? filter
71+
: Filter.and(this.whereFilter, filter);
72+
return this;
73+
}
74+
75+
/** Combine several conditions using with an AND operator. */
76+
public final Builder filters(Filter... filters) {
77+
Arrays.stream(filters).map(this::filters);
78+
return this;
79+
}
80+
5881
@SafeVarargs
5982
public final Builder metrics(PropertyAggregation... metrics) {
6083
this.metrics = Arrays.asList(metrics);
@@ -80,6 +103,12 @@ public void appendTo(WeaviateProtoAggregate.AggregateRequest.Builder req) {
80103
req.setObjectLimit(objectLimit);
81104
}
82105

106+
if (whereFilter != null) {
107+
var protoFilters = WeaviateProtoBase.Filters.newBuilder();
108+
whereFilter.appendTo(protoFilters);
109+
req.setFilters(protoFilters);
110+
}
111+
83112
for (final var metric : returnMetrics) {
84113
var aggregation = WeaviateProtoAggregate.AggregateRequest.Aggregation.newBuilder();
85114
metric.appendTo(aggregation);

0 commit comments

Comments
 (0)