Skip to content

Commit ab9752c

Browse files
authored
Merge branch 'v6' into v6-weaviate-object
2 parents cd5a1eb + 6befa30 commit ab9752c

29 files changed

Lines changed: 436 additions & 46 deletions

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/SearchITest.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@
2323
import io.weaviate.client6.v1.api.WeaviateClient;
2424
import io.weaviate.client6.v1.api.collections.Property;
2525
import io.weaviate.client6.v1.api.collections.ReferenceProperty;
26+
import io.weaviate.client6.v1.api.collections.Reranker;
2627
import io.weaviate.client6.v1.api.collections.VectorConfig;
2728
import io.weaviate.client6.v1.api.collections.Vectors;
2829
import io.weaviate.client6.v1.api.collections.WeaviateMetadata;
2930
import io.weaviate.client6.v1.api.collections.data.Reference;
3031
import io.weaviate.client6.v1.api.collections.data.WriteWeaviateObject;
31-
import io.weaviate.client6.v1.api.collections.generate.GenerativeObject;
32+
import io.weaviate.client6.v1.api.collections.generate.
3233
import io.weaviate.client6.v1.api.collections.generate.TaskOutput;
3334
import io.weaviate.client6.v1.api.collections.generative.DummyGenerative;
3435
import io.weaviate.client6.v1.api.collections.query.Filter;
@@ -37,8 +38,10 @@
3738
import io.weaviate.client6.v1.api.collections.query.QueryMetadata;
3839
import io.weaviate.client6.v1.api.collections.query.QueryResponseGroup;
3940
import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject;
41+
import io.weaviate.client6.v1.api.collections.query.Rerank;
4042
import io.weaviate.client6.v1.api.collections.query.SortBy;
4143
import io.weaviate.client6.v1.api.collections.query.Target;
44+
import io.weaviate.client6.v1.api.collections.rerankers.DummyReranker;
4245
import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw;
4346
import io.weaviate.client6.v1.api.collections.vectorindex.MultiVector;
4447
import io.weaviate.containers.Container;
@@ -52,7 +55,7 @@ public class SearchITest extends ConcurrentTest {
5255
Weaviate.custom()
5356
.withModel2VecUrl(Model2Vec.URL)
5457
.withImageInference(Img2VecNeural.URL, Img2VecNeural.MODULE)
55-
.addModules("generative-dummy")
58+
.addModules(Generative.Kind.DUMMY.jsonValue(), Reranker.Kind.DUMMY.jsonValue())
5659
.build(),
5760
Container.IMG2VEC_NEURAL,
5861
Container.MODEL2VEC);
@@ -765,4 +768,30 @@ public void test_maxGrpcMessageSize() throws Exception {
765768
}).isInstanceOf(io.grpc.StatusRuntimeException.class);
766769
}
767770
}
771+
772+
@Test
773+
public void test_rerankQueries() throws IOException {
774+
// Arrange
775+
var nsThigns = ns("Things");
776+
777+
var things = client.collections.create(nsThigns,
778+
c -> c
779+
.properties(Property.text("title"), Property.integer("price"))
780+
.vectorConfig(VectorConfig.text2vecModel2Vec(
781+
t2v -> t2v.sourceProperties("title", "price")))
782+
.rerankerModules(new DummyReranker()));
783+
784+
things.data.insertMany(
785+
Map.of("title", "Ergonomic chair", "price", 269),
786+
Map.of("title", "Height-adjustable desk", "price", 349));
787+
788+
// Act
789+
var got = things.query.nearText(
790+
"office supplies",
791+
nt -> nt.rerank(Rerank.by("price",
792+
rank -> rank.query("cheaper first"))));
793+
794+
// Assert: ranking not important really, just that the request was valid.
795+
Assertions.assertThat(got.objects()).hasSize(2);
796+
}
768797
}

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
@@ -275,19 +275,23 @@ public void write(JsonWriter out, CollectionConfig value) throws IOException {
275275
// Reranker and Generative module configs belong to the "moduleConfig".
276276
var rerankerModules = jsonObject.remove("rerankerModules").getAsJsonArray();
277277
var generativeModule = jsonObject.remove("generativeModule");
278-
if (!rerankerModules.isEmpty() || !generativeModule.isJsonNull()) {
279-
var modules = new JsonObject();
280278

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

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

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

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)