From 8501ef8df8d9279f451965fc5050bef4870a8cbc Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Tue, 24 Jun 2025 21:41:28 +0200 Subject: [PATCH 01/11] feat: add Near queries and aggregations --- .../aggregate/AbstractAggregateClient.java | 155 ++++++++++++++++++ .../query/AbstractQueryClient.java | 135 +++++++++++++++ .../v1/api/collections/query/NearAudio.java | 66 ++++++++ .../v1/api/collections/query/NearDepth.java | 66 ++++++++ .../v1/api/collections/query/NearImage.java | 23 +-- .../v1/api/collections/query/NearImu.java | 66 ++++++++ .../collections/query/NearMediaBuilder.java | 27 +++ .../v1/api/collections/query/NearThermal.java | 66 ++++++++ .../v1/api/collections/query/NearVideo.java | 66 ++++++++ 9 files changed, 650 insertions(+), 20 deletions(-) create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/NearAudio.java create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/NearDepth.java create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/NearImu.java create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/NearMediaBuilder.java create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/NearThermal.java create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/NearVideo.java diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java index c63c9ff9..5af0a639 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java @@ -3,9 +3,14 @@ import java.util.List; import java.util.function.Function; +import io.weaviate.client6.v1.api.collections.query.NearAudio; +import io.weaviate.client6.v1.api.collections.query.NearDepth; import io.weaviate.client6.v1.api.collections.query.NearImage; +import io.weaviate.client6.v1.api.collections.query.NearImu; import io.weaviate.client6.v1.api.collections.query.NearText; +import io.weaviate.client6.v1.api.collections.query.NearThermal; import io.weaviate.client6.v1.api.collections.query.NearVector; +import io.weaviate.client6.v1.api.collections.query.NearVideo; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; @@ -141,4 +146,154 @@ public GroupedResponseT nearImage(NearImage filter, Function> fn) { + return nearAudio(NearAudio.of(audio), fn); + } + + public ResponseT nearAudio(String audio, Function> nv, + Function> fn) { + return nearAudio(NearAudio.of(audio, nv), fn); + } + + public ResponseT nearAudio(NearAudio filter, Function> fn) { + return performRequest(Aggregation.of(filter, fn)); + } + + public GroupedResponseT nearAudio(String audio, Function> fn, + GroupBy groupBy) { + return nearAudio(NearAudio.of(audio), fn, groupBy); + } + + public GroupedResponseT nearAudio(String audio, Function> nv, + Function> fn, GroupBy groupBy) { + return nearAudio(NearAudio.of(audio, nv), fn, groupBy); + } + + public GroupedResponseT nearAudio(NearAudio filter, Function> fn, + GroupBy groupBy) { + return performRequest(Aggregation.of(filter, fn), groupBy); + } + + // NearVideo ---------------------------------------------------------------- + + public ResponseT nearVideo(String video, Function> fn) { + return nearVideo(NearVideo.of(video), fn); + } + + public ResponseT nearVideo(String video, Function> nv, + Function> fn) { + return nearVideo(NearVideo.of(video, nv), fn); + } + + public ResponseT nearVideo(NearVideo filter, Function> fn) { + return performRequest(Aggregation.of(filter, fn)); + } + + public GroupedResponseT nearVideo(String video, Function> fn, + GroupBy groupBy) { + return nearVideo(NearVideo.of(video), fn, groupBy); + } + + public GroupedResponseT nearVideo(String video, Function> nv, + Function> fn, GroupBy groupBy) { + return nearVideo(NearVideo.of(video, nv), fn, groupBy); + } + + public GroupedResponseT nearVideo(NearVideo filter, Function> fn, + GroupBy groupBy) { + return performRequest(Aggregation.of(filter, fn), groupBy); + } + + // NearThermal -------------------------------------------------------------- + + public ResponseT nearThermal(String thermal, Function> fn) { + return nearThermal(NearThermal.of(thermal), fn); + } + + public ResponseT nearThermal(String thermal, Function> nv, + Function> fn) { + return nearThermal(NearThermal.of(thermal, nv), fn); + } + + public ResponseT nearThermal(NearThermal filter, Function> fn) { + return performRequest(Aggregation.of(filter, fn)); + } + + public GroupedResponseT nearThermal(String thermal, Function> fn, + GroupBy groupBy) { + return nearThermal(NearThermal.of(thermal), fn, groupBy); + } + + public GroupedResponseT nearThermal(String thermal, Function> nv, + Function> fn, GroupBy groupBy) { + return nearThermal(NearThermal.of(thermal, nv), fn, groupBy); + } + + public GroupedResponseT nearThermal(NearThermal filter, Function> fn, + GroupBy groupBy) { + return performRequest(Aggregation.of(filter, fn), groupBy); + } + + // NearDepth -------------------------------------------------------------- + + public ResponseT nearDepth(String depth, Function> fn) { + return nearDepth(NearDepth.of(depth), fn); + } + + public ResponseT nearDepth(String depth, Function> nv, + Function> fn) { + return nearDepth(NearDepth.of(depth, nv), fn); + } + + public ResponseT nearDepth(NearDepth filter, Function> fn) { + return performRequest(Aggregation.of(filter, fn)); + } + + public GroupedResponseT nearDepth(String depth, Function> fn, + GroupBy groupBy) { + return nearDepth(NearDepth.of(depth), fn, groupBy); + } + + public GroupedResponseT nearDepth(String depth, Function> nv, + Function> fn, GroupBy groupBy) { + return nearDepth(NearDepth.of(depth, nv), fn, groupBy); + } + + public GroupedResponseT nearDepth(NearDepth filter, Function> fn, + GroupBy groupBy) { + return performRequest(Aggregation.of(filter, fn), groupBy); + } + + // NearImu ------------------------------------------------------------------ + + public ResponseT nearImu(String imu, Function> fn) { + return nearImu(NearImu.of(imu), fn); + } + + public ResponseT nearImu(String imu, Function> nv, + Function> fn) { + return nearImu(NearImu.of(imu, nv), fn); + } + + public ResponseT nearImu(NearImu filter, Function> fn) { + return performRequest(Aggregation.of(filter, fn)); + } + + public GroupedResponseT nearImu(String imu, Function> fn, + GroupBy groupBy) { + return nearImu(NearImu.of(imu), fn, groupBy); + } + + public GroupedResponseT nearImu(String imu, Function> nv, + Function> fn, GroupBy groupBy) { + return nearImu(NearImu.of(imu, nv), fn, groupBy); + } + + public GroupedResponseT nearImu(NearImu filter, Function> fn, + GroupBy groupBy) { + return performRequest(Aggregation.of(filter, fn), groupBy); + } } 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 f0ada511..c00bc0fc 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 @@ -175,4 +175,139 @@ public GroupedResponseT nearImage(String image, Function> fn) { + return nearAudio(NearAudio.of(audio, fn)); + } + + public ResponseT nearAudio(NearAudio query) { + return performRequest(query); + } + + public GroupedResponseT nearAudio(String audio, GroupBy groupBy) { + return nearAudio(NearAudio.of(audio), groupBy); + } + + public GroupedResponseT nearAudio(String audio, Function> fn, + GroupBy groupBy) { + return nearAudio(NearAudio.of(audio, fn), groupBy); + } + + public GroupedResponseT nearAudio(NearAudio query, GroupBy groupBy) { + return performRequest(query, groupBy); + } + + // NearVideo queries -------------------------------------------------------- + + public ResponseT nearVideo(String video) { + return nearVideo(NearVideo.of(video)); + } + + public ResponseT nearVideo(String video, Function> fn) { + return nearVideo(NearVideo.of(video, fn)); + } + + public ResponseT nearVideo(NearVideo query) { + return performRequest(query); + } + + public GroupedResponseT nearVideo(String video, GroupBy groupBy) { + return nearVideo(NearVideo.of(video), groupBy); + } + + public GroupedResponseT nearVideo(String video, Function> fn, + GroupBy groupBy) { + return nearVideo(NearVideo.of(video, fn), groupBy); + } + + public GroupedResponseT nearVideo(NearVideo query, GroupBy groupBy) { + return performRequest(query, groupBy); + } + + // NearThermal queries ------------------------------------------------------ + + public ResponseT nearThermal(String thermal) { + return nearThermal(NearThermal.of(thermal)); + } + + public ResponseT nearThermal(String thermal, Function> fn) { + return nearThermal(NearThermal.of(thermal, fn)); + } + + public ResponseT nearThermal(NearThermal query) { + return performRequest(query); + } + + public GroupedResponseT nearThermal(String thermal, GroupBy groupBy) { + return nearThermal(NearThermal.of(thermal), groupBy); + } + + public GroupedResponseT nearThermal(String thermal, Function> fn, + GroupBy groupBy) { + return nearThermal(NearThermal.of(thermal, fn), groupBy); + } + + public GroupedResponseT nearThermal(NearThermal query, GroupBy groupBy) { + return performRequest(query, groupBy); + } + + // NearDepth queries -------------------------------------------------------- + + public ResponseT nearDepth(String depth) { + return nearDepth(NearDepth.of(depth)); + } + + public ResponseT nearDepth(String depth, Function> fn) { + return nearDepth(NearDepth.of(depth, fn)); + } + + public ResponseT nearDepth(NearDepth query) { + return performRequest(query); + } + + public GroupedResponseT nearDepth(String depth, GroupBy groupBy) { + return nearDepth(NearDepth.of(depth), groupBy); + } + + public GroupedResponseT nearDepth(String depth, Function> fn, + GroupBy groupBy) { + return nearDepth(NearDepth.of(depth, fn), groupBy); + } + + public GroupedResponseT nearDepth(NearDepth query, GroupBy groupBy) { + return performRequest(query, groupBy); + } + + // NearImu queries ---------------------------------------------------------- + + public ResponseT nearImu(String imu) { + return nearImu(NearImu.of(imu)); + } + + public ResponseT nearImu(String imu, Function> fn) { + return nearImu(NearImu.of(imu, fn)); + } + + public ResponseT nearImu(NearImu query) { + return performRequest(query); + } + + public GroupedResponseT nearImu(String imu, GroupBy groupBy) { + return nearImu(NearImu.of(imu), groupBy); + } + + public GroupedResponseT nearImu(String imu, Function> fn, + GroupBy groupBy) { + return nearImu(NearImu.of(imu, fn), groupBy); + } + + public GroupedResponseT nearImu(NearImu query, GroupBy groupBy) { + return performRequest(query, groupBy); + } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearAudio.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearAudio.java new file mode 100644 index 00000000..491ac3d3 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearAudio.java @@ -0,0 +1,66 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.function.Function; + +import io.weaviate.client6.v1.api.collections.aggregate.AggregateObjectFilter; +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoAggregate; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBaseSearch; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; + +public record NearAudio(String audio, Float distance, Float certainty, BaseQueryOptions common) + implements QueryOperator, AggregateObjectFilter { + + public static NearAudio of(String audio) { + return of(audio, ObjectBuilder.identity()); + } + + public static NearAudio of(String audio, Function> fn) { + return fn.apply(new Builder(audio)).build(); + } + + public NearAudio(Builder builder) { + this( + builder.media, + builder.distance, + builder.certainty, + builder.baseOptions()); + } + + public static class Builder extends NearMediaBuilder { + public Builder(String audio) { + super(audio); + } + + @Override + public final NearAudio build() { + return new NearAudio(this); + } + } + + @Override + public void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + common.appendTo(req); + req.setNearAudio(protoBuilder()); + } + + @Override + public void appendTo(WeaviateProtoAggregate.AggregateRequest.Builder req) { + if (common.limit() != null) { + req.setLimit(common.limit()); + } + req.setNearAudio(protoBuilder()); + } + + private WeaviateProtoBaseSearch.NearAudioSearch.Builder protoBuilder() { + var nearAudio = WeaviateProtoBaseSearch.NearAudioSearch.newBuilder(); + nearAudio.setAudio(audio); + + if (certainty != null) { + nearAudio.setCertainty(certainty); + } else if (distance != null) { + nearAudio.setDistance(distance); + } + return nearAudio; + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearDepth.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearDepth.java new file mode 100644 index 00000000..ded98f53 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearDepth.java @@ -0,0 +1,66 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.function.Function; + +import io.weaviate.client6.v1.api.collections.aggregate.AggregateObjectFilter; +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoAggregate; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBaseSearch; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; + +public record NearDepth(String depth, Float distance, Float certainty, BaseQueryOptions common) + implements QueryOperator, AggregateObjectFilter { + + public static NearDepth of(String depth) { + return of(depth, ObjectBuilder.identity()); + } + + public static NearDepth of(String depth, Function> fn) { + return fn.apply(new Builder(depth)).build(); + } + + public NearDepth(Builder builder) { + this( + builder.media, + builder.distance, + builder.certainty, + builder.baseOptions()); + } + + public static class Builder extends NearMediaBuilder { + public Builder(String depth) { + super(depth); + } + + @Override + public final NearDepth build() { + return new NearDepth(this); + } + } + + @Override + public void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + common.appendTo(req); + req.setNearDepth(protoBuilder()); + } + + @Override + public void appendTo(WeaviateProtoAggregate.AggregateRequest.Builder req) { + if (common.limit() != null) { + req.setLimit(common.limit()); + } + req.setNearDepth(protoBuilder()); + } + + private WeaviateProtoBaseSearch.NearDepthSearch.Builder protoBuilder() { + var nearDepth = WeaviateProtoBaseSearch.NearDepthSearch.newBuilder(); + nearDepth.setDepth(depth); + + if (certainty != null) { + nearDepth.setCertainty(certainty); + } else if (distance != null) { + nearDepth.setDistance(distance); + } + return nearDepth; + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearImage.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearImage.java index 6fb9ef96..ab6c6281 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearImage.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearImage.java @@ -21,32 +21,15 @@ public static NearImage of(String image, Function { - // Required query parameters. - private final String image; - - // Optional query parameters. - private Float distance; - private Float certainty; - + public static class Builder extends NearMediaBuilder { public Builder(String image) { - this.image = image; - } - - public Builder distance(float distance) { - this.distance = distance; - return this; - } - - public Builder certainty(float certainty) { - this.certainty = certainty; - return this; + super(image); } @Override diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearImu.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearImu.java new file mode 100644 index 00000000..7246ba7d --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearImu.java @@ -0,0 +1,66 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.function.Function; + +import io.weaviate.client6.v1.api.collections.aggregate.AggregateObjectFilter; +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoAggregate; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBaseSearch; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; + +public record NearImu(String imu, Float distance, Float certainty, BaseQueryOptions common) + implements QueryOperator, AggregateObjectFilter { + + public static NearImu of(String imu) { + return of(imu, ObjectBuilder.identity()); + } + + public static NearImu of(String imu, Function> fn) { + return fn.apply(new Builder(imu)).build(); + } + + public NearImu(Builder builder) { + this( + builder.media, + builder.distance, + builder.certainty, + builder.baseOptions()); + } + + public static class Builder extends NearMediaBuilder { + public Builder(String imu) { + super(imu); + } + + @Override + public final NearImu build() { + return new NearImu(this); + } + } + + @Override + public void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + common.appendTo(req); + req.setNearImu(protoBuilder()); + } + + @Override + public void appendTo(WeaviateProtoAggregate.AggregateRequest.Builder req) { + if (common.limit() != null) { + req.setLimit(common.limit()); + } + req.setNearImu(protoBuilder()); + } + + private WeaviateProtoBaseSearch.NearIMUSearch.Builder protoBuilder() { + var nearImu = WeaviateProtoBaseSearch.NearIMUSearch.newBuilder(); + nearImu.setImu(imu); + + if (certainty != null) { + nearImu.setCertainty(certainty); + } else if (distance != null) { + nearImu.setDistance(distance); + } + return nearImu; + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearMediaBuilder.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearMediaBuilder.java new file mode 100644 index 00000000..64cf86ef --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearMediaBuilder.java @@ -0,0 +1,27 @@ +package io.weaviate.client6.v1.api.collections.query; + +abstract class NearMediaBuilder + extends BaseQueryOptions.Builder, MediaT> { + // Required query parameters. + final String media; + + // Optional query parameters. + Float distance; + Float certainty; + + public NearMediaBuilder(String media) { + this.media = media; + } + + @SuppressWarnings("unchecked") + public SelfT distance(float distance) { + this.distance = distance; + return (SelfT) this; + } + + @SuppressWarnings("unchecked") + public SelfT certainty(float certainty) { + this.certainty = certainty; + return (SelfT) this; + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearThermal.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearThermal.java new file mode 100644 index 00000000..26efdc41 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearThermal.java @@ -0,0 +1,66 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.function.Function; + +import io.weaviate.client6.v1.api.collections.aggregate.AggregateObjectFilter; +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoAggregate; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBaseSearch; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; + +public record NearThermal(String thermal, Float distance, Float certainty, BaseQueryOptions common) + implements QueryOperator, AggregateObjectFilter { + + public static NearThermal of(String thermal) { + return of(thermal, ObjectBuilder.identity()); + } + + public static NearThermal of(String thermal, Function> fn) { + return fn.apply(new Builder(thermal)).build(); + } + + public NearThermal(Builder builder) { + this( + builder.media, + builder.distance, + builder.certainty, + builder.baseOptions()); + } + + public static class Builder extends NearMediaBuilder { + public Builder(String thermal) { + super(thermal); + } + + @Override + public final NearThermal build() { + return new NearThermal(this); + } + } + + @Override + public void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + common.appendTo(req); + req.setNearThermal(protoBuilder()); + } + + @Override + public void appendTo(WeaviateProtoAggregate.AggregateRequest.Builder req) { + if (common.limit() != null) { + req.setLimit(common.limit()); + } + req.setNearThermal(protoBuilder()); + } + + private WeaviateProtoBaseSearch.NearThermalSearch.Builder protoBuilder() { + var nearThermal = WeaviateProtoBaseSearch.NearThermalSearch.newBuilder(); + nearThermal.setThermal(thermal); + + if (certainty != null) { + nearThermal.setCertainty(certainty); + } else if (distance != null) { + nearThermal.setDistance(distance); + } + return nearThermal; + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVideo.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVideo.java new file mode 100644 index 00000000..0968221c --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVideo.java @@ -0,0 +1,66 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.function.Function; + +import io.weaviate.client6.v1.api.collections.aggregate.AggregateObjectFilter; +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoAggregate; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBaseSearch; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; + +public record NearVideo(String video, Float distance, Float certainty, BaseQueryOptions common) + implements QueryOperator, AggregateObjectFilter { + + public static NearVideo of(String video) { + return of(video, ObjectBuilder.identity()); + } + + public static NearVideo of(String video, Function> fn) { + return fn.apply(new Builder(video)).build(); + } + + public NearVideo(Builder builder) { + this( + builder.media, + builder.distance, + builder.certainty, + builder.baseOptions()); + } + + public static class Builder extends NearMediaBuilder { + public Builder(String video) { + super(video); + } + + @Override + public final NearVideo build() { + return new NearVideo(this); + } + } + + @Override + public void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + common.appendTo(req); + req.setNearVideo(protoBuilder()); + } + + @Override + public void appendTo(WeaviateProtoAggregate.AggregateRequest.Builder req) { + if (common.limit() != null) { + req.setLimit(common.limit()); + } + req.setNearVideo(protoBuilder()); + } + + private WeaviateProtoBaseSearch.NearVideoSearch.Builder protoBuilder() { + var nearVideo = WeaviateProtoBaseSearch.NearVideoSearch.newBuilder(); + nearVideo.setVideo(video); + + if (certainty != null) { + nearVideo.setCertainty(certainty); + } else if (distance != null) { + nearVideo.setDistance(distance); + } + return nearVideo; + } +} From d69658f122ff33972b4a073bff427e06605f1e99 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Tue, 24 Jun 2025 22:01:35 +0200 Subject: [PATCH 02/11] feat: add nearObject query / aggregation --- .../aggregate/AbstractAggregateClient.java | 31 ++++++++ .../query/AbstractQueryClient.java | 27 +++++++ .../v1/api/collections/query/NearObject.java | 79 +++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java index 5af0a639..3444b622 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java @@ -7,6 +7,7 @@ import io.weaviate.client6.v1.api.collections.query.NearDepth; import io.weaviate.client6.v1.api.collections.query.NearImage; import io.weaviate.client6.v1.api.collections.query.NearImu; +import io.weaviate.client6.v1.api.collections.query.NearObject; import io.weaviate.client6.v1.api.collections.query.NearText; import io.weaviate.client6.v1.api.collections.query.NearThermal; import io.weaviate.client6.v1.api.collections.query.NearVector; @@ -68,6 +69,36 @@ public GroupedResponseT nearVector(NearVector filter, Function> fn) { + return nearObject(NearObject.of(uuid), fn); + } + + public ResponseT nearObject(String uuid, Function> nv, + Function> fn) { + return nearObject(NearObject.of(uuid, nv), fn); + } + + public ResponseT nearObject(NearObject filter, Function> fn) { + return performRequest(Aggregation.of(filter, fn)); + } + + public GroupedResponseT nearObject(String uuid, Function> fn, + GroupBy groupBy) { + return nearObject(NearObject.of(uuid), fn, groupBy); + } + + public GroupedResponseT nearObject(String uuid, Function> nv, + Function> fn, GroupBy groupBy) { + return nearObject(NearObject.of(uuid, nv), fn, groupBy); + } + + public GroupedResponseT nearObject(NearObject filter, Function> fn, + GroupBy groupBy) { + return performRequest(Aggregation.of(filter, fn), groupBy); + } + // NearText ----------------------------------------------------------------- public ResponseT nearText(String text, Function> fn) { 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 c00bc0fc..015dc516 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 @@ -109,6 +109,33 @@ public GroupedResponseT nearVector(NearVector query, GroupBy groupBy) { return performRequest(query, groupBy); } + // NearObject queries ------------------------------------------------------- + + public ResponseT nearObject(String uuid) { + return nearObject(NearObject.of(uuid)); + } + + public ResponseT nearObject(String uuid, Function> fn) { + return nearObject(NearObject.of(uuid, fn)); + } + + public ResponseT nearObject(NearObject query) { + return performRequest(query); + } + + public GroupedResponseT nearObject(String uuid, GroupBy groupBy) { + return nearObject(NearObject.of(uuid), groupBy); + } + + public GroupedResponseT nearObject(String uuid, Function> fn, + GroupBy groupBy) { + return nearObject(NearObject.of(uuid, fn), groupBy); + } + + public GroupedResponseT nearObject(NearObject query, GroupBy groupBy) { + return performRequest(query, groupBy); + } + // NearText queries --------------------------------------------------------- public ResponseT nearText(String... text) { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java new file mode 100644 index 00000000..8d77cad7 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java @@ -0,0 +1,79 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.function.Function; + +import io.weaviate.client6.v1.api.collections.aggregate.AggregateObjectFilter; +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoAggregate; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBaseSearch; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; + +public record NearObject(String uuid, Float distance, Float certainty, BaseQueryOptions common) + implements QueryOperator, AggregateObjectFilter { + + public static final NearObject of(String uuid) { + return of(uuid, ObjectBuilder.identity()); + } + + public static final NearObject of(String uuid, Function> fn) { + return fn.apply(new Builder(uuid)).build(); + } + + public NearObject(Builder builder) { + this(builder.uuid, builder.distance, builder.certainty, builder.baseOptions()); + } + + public static class Builder extends BaseQueryOptions.Builder { + // Required query parameters. + private final String uuid; + + // Optional query parameters. + private Float distance; + private Float certainty; + + public Builder(String uuid) { + this.uuid = uuid; + } + + public final Builder distance(float distance) { + this.distance = distance; + return this; + } + + public final Builder certainty(float certainty) { + this.certainty = certainty; + return this; + } + + @Override + public final NearObject build() { + return new NearObject(this); + } + } + + @Override + public final void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + common.appendTo(req); + req.setNearObject(protoBuilder()); + } + + @Override + public void appendTo(WeaviateProtoAggregate.AggregateRequest.Builder req) { + if (common.limit() != null) { + req.setLimit(common.limit()); + } + req.setNearObject(protoBuilder()); + } + + private WeaviateProtoBaseSearch.NearObject.Builder protoBuilder() { + var nearObject = WeaviateProtoBaseSearch.NearObject.newBuilder() + .setId(uuid); + + if (certainty != null) { + nearObject.setCertainty(certainty); + } else if (distance != null) { + nearObject.setDistance(distance); + } + return nearObject; + } +} From fea440c04818ff9f99bfff8c8484244d559f8010 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Tue, 24 Jun 2025 22:11:14 +0200 Subject: [PATCH 03/11] refactor: push common vector-search parameters to a base class --- .../query/BaseVectorSearchBuilder.java | 21 +++++++++++++++++++ .../collections/query/NearMediaBuilder.java | 20 ++---------------- .../v1/api/collections/query/NearObject.java | 16 +------------- .../v1/api/collections/query/NearText.java | 14 +------------ .../v1/api/collections/query/NearVector.java | 16 +------------- 5 files changed, 26 insertions(+), 61 deletions(-) create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/BaseVectorSearchBuilder.java diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseVectorSearchBuilder.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseVectorSearchBuilder.java new file mode 100644 index 00000000..08b385a1 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseVectorSearchBuilder.java @@ -0,0 +1,21 @@ +package io.weaviate.client6.v1.api.collections.query; + +abstract class BaseVectorSearchBuilder, NearT extends Object> + extends BaseQueryOptions.Builder { + + // Optional query parameters. + Float distance; + Float certainty; + + @SuppressWarnings("unchecked") + public SelfT distance(float distance) { + this.distance = distance; + return (SelfT) this; + } + + @SuppressWarnings("unchecked") + public SelfT certainty(float certainty) { + this.certainty = certainty; + return (SelfT) this; + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearMediaBuilder.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearMediaBuilder.java index 64cf86ef..1d81eeae 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearMediaBuilder.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearMediaBuilder.java @@ -1,27 +1,11 @@ package io.weaviate.client6.v1.api.collections.query; -abstract class NearMediaBuilder - extends BaseQueryOptions.Builder, MediaT> { +abstract class NearMediaBuilder, MediaT extends Object> + extends BaseVectorSearchBuilder { // Required query parameters. final String media; - // Optional query parameters. - Float distance; - Float certainty; - public NearMediaBuilder(String media) { this.media = media; } - - @SuppressWarnings("unchecked") - public SelfT distance(float distance) { - this.distance = distance; - return (SelfT) this; - } - - @SuppressWarnings("unchecked") - public SelfT certainty(float certainty) { - this.certainty = certainty; - return (SelfT) this; - } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java index 8d77cad7..97fafb93 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java @@ -23,28 +23,14 @@ public NearObject(Builder builder) { this(builder.uuid, builder.distance, builder.certainty, builder.baseOptions()); } - public static class Builder extends BaseQueryOptions.Builder { + public static class Builder extends BaseVectorSearchBuilder { // Required query parameters. private final String uuid; - // Optional query parameters. - private Float distance; - private Float certainty; - public Builder(String uuid) { this.uuid = uuid; } - public final Builder distance(float distance) { - this.distance = distance; - return this; - } - - public final Builder certainty(float certainty) { - this.certainty = certainty; - return this; - } - @Override public final NearObject build() { return new NearObject(this); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearText.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearText.java index 40b7c786..fe2761ae 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearText.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearText.java @@ -40,13 +40,11 @@ public NearText(Builder builder) { builder.baseOptions()); } - public static class Builder extends BaseQueryOptions.Builder { + public static class Builder extends BaseVectorSearchBuilder { // Required query parameters. private final List concepts; // Optional query parameter. - private Float distance; - private Float certainty; private Move moveTo; private Move moveAway; @@ -54,16 +52,6 @@ public Builder(List concepts) { this.concepts = concepts; } - public final Builder distance(float distance) { - this.distance = distance; - return this; - } - - public final Builder certainty(float certainty) { - this.certainty = certainty; - return this; - } - public final Builder moveTo(float force, Function> fn) { this.moveTo = fn.apply(new Move.Builder(force)).build(); return this; diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVector.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVector.java index c01cc52c..6ba8a921 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVector.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVector.java @@ -25,28 +25,14 @@ public NearVector(Builder builder) { this(builder.vector, builder.distance, builder.certainty, builder.baseOptions()); } - public static class Builder extends BaseQueryOptions.Builder { + public static class Builder extends BaseVectorSearchBuilder { // Required query parameters. private final Float[] vector; - // Optional query parameters. - private Float distance; - private Float certainty; - public Builder(Float[] vector) { this.vector = vector; } - public final Builder distance(float distance) { - this.distance = distance; - return this; - } - - public final Builder certainty(float certainty) { - this.certainty = certainty; - return this; - } - @Override public final NearVector build() { return new NearVector(this); From aa2cbd226fa4276c40d292613d1d225df5eed29e Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Tue, 24 Jun 2025 22:42:43 +0200 Subject: [PATCH 04/11] fix: pass SearchOperator to gRPC query --- .../client6/v1/api/collections/query/Bm25.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/Bm25.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/Bm25.java index acf056d0..be575455 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/Bm25.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/Bm25.java @@ -8,8 +8,11 @@ import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBaseSearch; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; -public record Bm25(String query, List queryProperties, BaseQueryOptions common) - implements QueryOperator { +public record Bm25( + String query, + List queryProperties, + SearchOperator searchOperator, + BaseQueryOptions common) implements QueryOperator { public static final Bm25 of(String query) { return of(query, ObjectBuilder.identity()); @@ -20,7 +23,7 @@ public static final Bm25 of(String query, Function> } public Bm25(Builder builder) { - this(builder.query, builder.queryProperties, builder.baseOptions()); + this(builder.query, builder.queryProperties, builder.searchOperator, builder.baseOptions()); } public static class Builder extends BaseQueryOptions.Builder { @@ -58,8 +61,13 @@ public final Bm25 build() { @Override public final void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { common.appendTo(req); - req.setBm25Search(WeaviateProtoBaseSearch.BM25.newBuilder() + var bm25 = WeaviateProtoBaseSearch.BM25.newBuilder() .setQuery(query) - .addAllProperties(queryProperties)); + .addAllProperties(queryProperties); + + if (searchOperator != null) { + searchOperator.appendTo(bm25); + } + req.setBm25Search(bm25); } } From bd31dd60f3f231550d15116a8969d381d2f0dfeb Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Tue, 24 Jun 2025 22:43:00 +0200 Subject: [PATCH 05/11] feat: add hybrid to query / aggregate --- .../aggregate/AbstractAggregateClient.java | 31 ++++ .../query/AbstractQueryClient.java | 26 +++ .../v1/api/collections/query/Hybrid.java | 174 ++++++++++++++++++ .../v1/api/collections/query/NearText.java | 3 +- .../v1/api/collections/query/NearVector.java | 3 +- .../api/collections/query/SearchOperator.java | 4 +- 6 files changed, 238 insertions(+), 3 deletions(-) create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/Hybrid.java diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java index 3444b622..23fce1bc 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.function.Function; +import io.weaviate.client6.v1.api.collections.query.Hybrid; import io.weaviate.client6.v1.api.collections.query.NearAudio; import io.weaviate.client6.v1.api.collections.query.NearDepth; import io.weaviate.client6.v1.api.collections.query.NearImage; @@ -39,6 +40,36 @@ public GroupedResponseT overAll(Function> fn) { + return hybrid(Hybrid.of(query), fn); + } + + public ResponseT hybrid(String query, Function> nv, + Function> fn) { + return hybrid(Hybrid.of(query, nv), fn); + } + + public ResponseT hybrid(Hybrid filter, Function> fn) { + return performRequest(Aggregation.of(filter, fn)); + } + + public GroupedResponseT hybrid(String query, Function> fn, + GroupBy groupBy) { + return hybrid(Hybrid.of(query), fn, groupBy); + } + + public GroupedResponseT hybrid(String query, Function> nv, + Function> fn, GroupBy groupBy) { + return hybrid(Hybrid.of(query, nv), fn, groupBy); + } + + public GroupedResponseT hybrid(Hybrid filter, Function> fn, + GroupBy groupBy) { + return performRequest(Aggregation.of(filter, fn), groupBy); + } + // NearVector --------------------------------------------------------------- public ResponseT nearVector(Float[] vector, Function> fn) { 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 015dc516..5d84e9f4 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 @@ -82,6 +82,32 @@ public GroupedResponseT bm25(Bm25 query, GroupBy groupBy) { return performRequest(query, groupBy); } + // Hybrid queries ----------------------------------------------------------- + + public ResponseT hybrid(String query) { + return hybrid(Hybrid.of(query)); + } + + public ResponseT hybrid(String query, Function> fn) { + return hybrid(Hybrid.of(query, fn)); + } + + public ResponseT hybrid(Hybrid query) { + return performRequest(query); + } + + public GroupedResponseT hybrid(String query, GroupBy groupBy) { + return hybrid(Hybrid.of(query), groupBy); + } + + public GroupedResponseT hybrid(String query, Function> fn, GroupBy groupBy) { + return hybrid(Hybrid.of(query, fn), groupBy); + } + + public GroupedResponseT hybrid(Hybrid query, GroupBy groupBy) { + return performRequest(query, groupBy); + } + // NearVector queries ------------------------------------------------------- public ResponseT nearVector(Float[] vector) { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/Hybrid.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/Hybrid.java new file mode 100644 index 00000000..0a42d8c8 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/Hybrid.java @@ -0,0 +1,174 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +import io.weaviate.client6.v1.api.collections.aggregate.AggregateObjectFilter; +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoAggregate; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBaseSearch; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; + +public record Hybrid( + String query, + List queryProperties, + SearchOperator searchOperator, + Float alpha, + QueryOperator near, + FusionType fusionType, + Float maxVectorDistance, + /** + * alpha: NUMBER = 0.7, + * vector: Optional[HybridVectorType] = None, + * query_properties: Optional[List[str]] = None, + * fusion_type: Optional[HybridFusion] = None, + * max_vector_distance: Optional[NUMBER] = None, + * limit: Optional[int] = None, + * offset: Optional[int] = None, + * bm25_operator: Optional[BM25OperatorOptions] = None, + * auto_limit: Optional[int] = None, + * filters: Optional[_Filters] = None, + * group_by: Optional[GroupBy] = None, + * rerank: Optional[Rerank] = None, + * target_vector: Optional[TargetVectorJoinType] = None, + * include_vector: INCLUDE_VECTOR = False, + * return_metadata: Optional[METADATA] = None, + * return_properties: Optional[ReturnProperties[TProperties]] = None, + * return_references: Optional[ReturnReferences[TReferences]] = None, + */ + BaseQueryOptions common) + implements QueryOperator, AggregateObjectFilter { + + public static enum FusionType { + RELATIVE_SCORE, RANKED; + } + + public static final Hybrid of(String query) { + return of(query, ObjectBuilder.identity()); + } + + public static final Hybrid of(String query, Function> fn) { + return fn.apply(new Builder(query)).build(); + } + + public Hybrid(Builder builder) { + this( + builder.query, + builder.queryProperties, + builder.searchOperator, + builder.alpha, + builder.near, + builder.fusionType, + builder.maxVectorDistance, + builder.baseOptions()); + } + + public static class Builder extends BaseQueryOptions.Builder { + // Required query parameters. + private final String query; + + // Optional query parameters. + List queryProperties; + SearchOperator searchOperator; + Float alpha; + QueryOperator near; + FusionType fusionType; + Float maxVectorDistance; + + public Builder(String query) { + this.query = query; + } + + public Builder queryProperties(String... properties) { + return queryProperties(Arrays.asList(properties)); + } + + public Builder queryProperties(List properties) { + this.queryProperties = properties; + return this; + } + + public Builder searchOperator(SearchOperator searchOperator) { + this.searchOperator = searchOperator; + return this; + } + + public Builder alpha(float alpha) { + this.alpha = alpha; + return this; + } + + public Builder fusionType(FusionType fusionType) { + this.fusionType = fusionType; + return this; + } + + public Builder maxVectorDistance(float maxVectorDistance) { + this.maxVectorDistance = maxVectorDistance; + return this; + } + + public Builder nearVector(NearVector nearVector) { + this.near = nearVector; + return this; + } + + public Builder nearText(NearText nearText) { + this.near = nearText; + return this; + } + + @Override + public final Hybrid build() { + return new Hybrid(this); + } + } + + @Override + public void appendTo(WeaviateProtoAggregate.AggregateRequest.Builder req) { + if (common.limit() != null) { + req.setLimit(common.limit()); + } + req.setHybrid(protoBuilder()); + } + + @Override + public final void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + common.appendTo(req); + req.setHybridSearch(protoBuilder()); + } + + private WeaviateProtoBaseSearch.Hybrid.Builder protoBuilder() { + var hybrid = WeaviateProtoBaseSearch.Hybrid.newBuilder() + .setQuery(query) + .addAllProperties(queryProperties); + + if (alpha != null) { + hybrid.setAlpha(alpha); + } + + if (fusionType != null) { + switch (fusionType) { + case RANKED: + hybrid.setFusionType(WeaviateProtoBaseSearch.Hybrid.FusionType.FUSION_TYPE_RANKED); + case RELATIVE_SCORE: + hybrid.setFusionType(WeaviateProtoBaseSearch.Hybrid.FusionType.FUSION_TYPE_RELATIVE_SCORE); + } + } + + if (maxVectorDistance != null) { + hybrid.setVectorDistance(maxVectorDistance); + } + + if (near != null) { + if (near instanceof NearVector nv) { + hybrid.setNearVector(nv.protoBuilder()); + } else if (near instanceof NearText nt) { + hybrid.setNearText(nt.protoBuilder()); + } + } + + return hybrid; + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearText.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearText.java index fe2761ae..bd3131b2 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearText.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearText.java @@ -125,7 +125,8 @@ public void appendTo(WeaviateProtoAggregate.AggregateRequest.Builder req) { req.setNearText(protoBuilder()); } - private WeaviateProtoBaseSearch.NearTextSearch.Builder protoBuilder() { + // Package-private for Hybrid to see. + WeaviateProtoBaseSearch.NearTextSearch.Builder protoBuilder() { var nearText = WeaviateProtoBaseSearch.NearTextSearch.newBuilder(); nearText.addAllQuery(concepts); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVector.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVector.java index 6ba8a921..d5f2525c 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVector.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearVector.java @@ -53,7 +53,8 @@ public void appendTo(WeaviateProtoAggregate.AggregateRequest.Builder req) { req.setNearVector(protoBuilder()); } - private WeaviateProtoBaseSearch.NearVector.Builder protoBuilder() { + // This is made package-private for Hybrid to see. Should we refactor? + WeaviateProtoBaseSearch.NearVector.Builder protoBuilder() { var nearVector = WeaviateProtoBaseSearch.NearVector.newBuilder(); nearVector.addVectors(WeaviateProtoBase.Vectors.newBuilder() .setType(WeaviateProtoBase.Vectors.VectorType.VECTOR_TYPE_SINGLE_FP32) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/SearchOperator.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/SearchOperator.java index 4e1b3b62..8fa1ee1e 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/SearchOperator.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/SearchOperator.java @@ -20,10 +20,12 @@ private SearchOperator(String operator, Integer minimumOrTokensMatch) { this.minimumOrTokensMatch = minimumOrTokensMatch; } - void appendTo(WeaviateProtoBaseSearch.SearchOperatorOptions.Builder options) { + void appendTo(WeaviateProtoBaseSearch.BM25.Builder req) { + var options = WeaviateProtoBaseSearch.SearchOperatorOptions.newBuilder(); options.setOperator(operator == "And" ? Operator.OPERATOR_AND : Operator.OPERATOR_OR); if (minimumOrTokensMatch != null) { options.setMinimumOrTokensMatch(minimumOrTokensMatch); } + req.setSearchOperator(options); } } From 6f398245675b24529c46e79651b257cf1aa1bd97 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 25 Jun 2025 19:12:10 +0200 Subject: [PATCH 06/11] feat: add Where.uuid() helper to filter by object UUID --- .../io/weaviate/client6/v1/api/collections/query/Where.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java index 65379a51..ede568b1 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java @@ -90,6 +90,10 @@ public static Where or(List operands) { // Comparison operators return fluid builder. // -------------------------------------------------------------------------- + public static WhereBuilder uuid() { + return property("_id"); + } + public static WhereBuilder property(String property) { return new WhereBuilder(new PathOperand(property)); } @@ -564,7 +568,6 @@ private PathOperand(List path) { this.path = path; } - @SafeVarargs private PathOperand(String... path) { this(Arrays.asList(path)); } From 877aeb1ae50828117b9fa24cf91e37260cd065b7 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 25 Jun 2025 19:14:26 +0200 Subject: [PATCH 07/11] feat: add NearObject.excludeSelf() helper to not include the object itself in the result set --- .../weaviate/client6/v1/api/collections/query/NearObject.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java index 97fafb93..33e389e4 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/NearObject.java @@ -31,6 +31,10 @@ public Builder(String uuid) { this.uuid = uuid; } + public Builder excludeSelf() { + return where(Where.uuid().ne(uuid)); + } + @Override public final NearObject build() { return new NearObject(this); From b7bf6ea48c8a4e264330a161a90a92b75765c1e4 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 25 Jun 2025 19:55:59 +0200 Subject: [PATCH 08/11] feat: merge subsequent calls to .where() builder This allows higher-level queries like NearObject to add filters without overwriting the ones set by users. In general, this lets users call .where() multiple times, in line with the principle of 'append-only' options. --- .../collections/query/BaseQueryOptions.java | 9 ++- .../v1/api/collections/query/Where.java | 67 ++++++++++++++++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java index 0ac29d7e..11eb8770 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java @@ -72,8 +72,15 @@ public final SELF consistencyLevel(ConsistencyLevel consistencyLevel) { return (SELF) this; } + /** + * Filter result set using traditional filtering operators: {@code eq}, + * {@code gte}, {@code like}, etc. + * Subsequent calls to {@link #where} aggregate with an AND operator. + * + * @see {@link Where} + */ public final SELF where(Where where) { - this.where = where; + this.where = this.where == null ? where : Where.and(this.where, where); return (SELF) this; } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java index ede568b1..418600e7 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java @@ -69,6 +69,12 @@ public boolean isEmpty() { || operands.stream().allMatch(operator -> operator.isEmpty()); } + @Override + public String toString() { + var operandStrings = operands.stream().map(Object::toString).toList(); + return "Where(" + String.join(" " + operator.toString() + " ", operandStrings) + ")"; + } + // Logical operators return a complete operand. // -------------------------------------------------------------------------- public static Where and(WhereOperand... operands) { @@ -580,6 +586,11 @@ public void appendTo(WeaviateProtoBase.Filters.Builder where) { } // FIXME: no way to reference objects rn? } + + @Override + public String toString() { + return String.join("::", path); + } } private static class TextOperand implements WhereOperand { @@ -593,6 +604,11 @@ private TextOperand(String value) { public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueText(value); } + + @Override + public String toString() { + return value; + } } private static class TextArrayOperand implements WhereOperand { @@ -611,6 +627,11 @@ private TextArrayOperand(String... values) { public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueTextArray(WeaviateProtoBase.TextArray.newBuilder().addAllValues(values)); } + + @Override + public String toString() { + return values.toString(); + } } private static class BooleanOperand implements WhereOperand { @@ -624,6 +645,11 @@ private BooleanOperand(Boolean value) { public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueBoolean(value); } + + @Override + public String toString() { + return value.toString(); + } } private static class BooleanArrayOperand implements WhereOperand { @@ -642,6 +668,11 @@ private BooleanArrayOperand(Boolean... values) { public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueBooleanArray(WeaviateProtoBase.BooleanArray.newBuilder().addAllValues(values)); } + + @Override + public String toString() { + return values.toString(); + } } private static class IntegerOperand implements WhereOperand { @@ -655,6 +686,11 @@ private IntegerOperand(Integer value) { public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueInt(value); } + + @Override + public String toString() { + return value.toString(); + } } private static class IntegerArrayOperand implements WhereOperand { @@ -677,6 +713,11 @@ private List toLongs() { public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueIntArray(WeaviateProtoBase.IntArray.newBuilder().addAllValues(toLongs())); } + + @Override + public String toString() { + return values.toString(); + } } private static class NumberOperand implements WhereOperand { @@ -690,6 +731,11 @@ private NumberOperand(Number value) { public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueNumber(value.doubleValue()); } + + @Override + public String toString() { + return value.toString(); + } } private static class NumberArrayOperand implements WhereOperand { @@ -712,6 +758,11 @@ private List toDoubles() { public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueNumberArray(WeaviateProtoBase.NumberArray.newBuilder().addAllValues(toDoubles())); } + + @Override + public String toString() { + return values.toString(); + } } private static class DateOperand implements WhereOperand { @@ -729,6 +780,11 @@ private static String format(Date date) { public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueText(format(value)); } + + @Override + public String toString() { + return format(value); + } } private static class DateArrayOperand implements WhereOperand { @@ -745,13 +801,17 @@ private DateArrayOperand(Date... values) { private List formatted() { return values.stream().map(date -> DateOperand.format(date)).toList(); - } @Override public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueTextArray(WeaviateProtoBase.TextArray.newBuilder().addAllValues(formatted())); } + + @Override + public String toString() { + return values.toString(); + } } private static class GeoRangeOperand implements WhereOperand { @@ -770,5 +830,10 @@ public void appendTo(WeaviateProtoBase.Filters.Builder where) { where.setValueGeo(WeaviateProtoBase.GeoCoordinatesFilter.newBuilder() .setLatitude(lat).setLongitude(lon).setDistance(distance)); } + + @Override + public String toString() { + return "(lat=%d, lon=%d, distance=%d)".formatted(lat, lon, distance); + } } } From 5841541e06c53faeaaccd024e002ecc7facec3e1 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 25 Jun 2025 19:56:24 +0200 Subject: [PATCH 09/11] test: add integration test for NearObject query --- .../io/weaviate/integration/SearchITest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/it/java/io/weaviate/integration/SearchITest.java b/src/it/java/io/weaviate/integration/SearchITest.java index 2c895a90..b153679d 100644 --- a/src/it/java/io/weaviate/integration/SearchITest.java +++ b/src/it/java/io/weaviate/integration/SearchITest.java @@ -19,6 +19,7 @@ import io.weaviate.client6.v1.api.WeaviateClient; import io.weaviate.client6.v1.api.collections.Property; 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.query.GroupBy; @@ -315,4 +316,33 @@ public void testBm25_async() throws IOException, InterruptedException, Execution .containsOnly(want.metadata().uuid()); } } + + @Test + public void testNearObject() throws IOException { + // Arrange + var nsAnimals = ns("Animals"); + + client.collections.create(nsAnimals, + collection -> collection + .properties(Property.text("kind")) + .vector(Hnsw.of(Text2VecContextionaryVectorizer.of()))); + + var animals = client.collections.use(nsAnimals); + + // Terrestrial animals + var cat = animals.data.insert(Map.of("kind", "cat")); + var lion = animals.data.insert(Map.of("kind", "lion")); + // Aquatic animal + animals.data.insert(Map.of("kind", "dolphin")); + + // Act + var terrestrial = animals.query.nearObject(cat.metadata().uuid(), + q -> q.excludeSelf().limit(1)); + + // Assert + Assertions.assertThat(terrestrial.objects()) + .hasSize(1) + .extracting(WeaviateObject::metadata).extracting(WeaviateMetadata::uuid) + .containsOnly(lion.metadata().uuid()); + } } From 686d486f12df448ab7cc273beba4c6e25359ad7d Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 25 Jun 2025 20:16:31 +0200 Subject: [PATCH 10/11] fix: provide default queryProperties in Hybrid query Add integration test for Hybrid. --- .../io/weaviate/integration/SearchITest.java | 23 +++++++++++++++++++ .../v1/api/collections/query/Hybrid.java | 22 ++---------------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/it/java/io/weaviate/integration/SearchITest.java b/src/it/java/io/weaviate/integration/SearchITest.java index b153679d..4d69a82f 100644 --- a/src/it/java/io/weaviate/integration/SearchITest.java +++ b/src/it/java/io/weaviate/integration/SearchITest.java @@ -345,4 +345,27 @@ public void testNearObject() throws IOException { .extracting(WeaviateObject::metadata).extracting(WeaviateMetadata::uuid) .containsOnly(lion.metadata().uuid()); } + + @Test + public void testHybrid() throws IOException { + // Arrange + var nsHobbies = ns("Hobbies"); + + client.collections.create(nsHobbies, + collection -> collection + .properties(Property.text("name"), Property.text("description")) + .vector(Hnsw.of(Text2VecContextionaryVectorizer.of()))); + + var hobbies = client.collections.use(nsHobbies); + + var skiing = hobbies.data.insert(Map.of("name", "skiing", "description", "winter sport")); + hobbies.data.insert(Map.of("name", "jetskiing", "description", "water sport")); + + // Act + var winterSport = hobbies.query.hybrid("winter"); + Assertions.assertThat(winterSport.objects()) + .hasSize(1) + .extracting(WeaviateObject::metadata).extracting(WeaviateMetadata::uuid) + .containsOnly(skiing.metadata().uuid()); + } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/Hybrid.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/Hybrid.java index 0a42d8c8..c67412b8 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/Hybrid.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/Hybrid.java @@ -1,5 +1,6 @@ package io.weaviate.client6.v1.api.collections.query; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Function; @@ -18,25 +19,6 @@ public record Hybrid( QueryOperator near, FusionType fusionType, Float maxVectorDistance, - /** - * alpha: NUMBER = 0.7, - * vector: Optional[HybridVectorType] = None, - * query_properties: Optional[List[str]] = None, - * fusion_type: Optional[HybridFusion] = None, - * max_vector_distance: Optional[NUMBER] = None, - * limit: Optional[int] = None, - * offset: Optional[int] = None, - * bm25_operator: Optional[BM25OperatorOptions] = None, - * auto_limit: Optional[int] = None, - * filters: Optional[_Filters] = None, - * group_by: Optional[GroupBy] = None, - * rerank: Optional[Rerank] = None, - * target_vector: Optional[TargetVectorJoinType] = None, - * include_vector: INCLUDE_VECTOR = False, - * return_metadata: Optional[METADATA] = None, - * return_properties: Optional[ReturnProperties[TProperties]] = None, - * return_references: Optional[ReturnReferences[TReferences]] = None, - */ BaseQueryOptions common) implements QueryOperator, AggregateObjectFilter { @@ -69,7 +51,7 @@ public static class Builder extends BaseQueryOptions.Builder { private final String query; // Optional query parameters. - List queryProperties; + List queryProperties = new ArrayList<>(); SearchOperator searchOperator; Float alpha; QueryOperator near; From 653a347ce81bef51e8ea349919e381f47b1ee9cf Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 25 Jun 2025 20:24:04 +0200 Subject: [PATCH 11/11] doc: fix javadoc Replace @see with See. Refactor ById to use the new Where.uuid() shorthand. --- .../client6/v1/api/collections/query/BaseQueryOptions.java | 3 ++- .../io/weaviate/client6/v1/api/collections/query/ById.java | 4 ++-- .../io/weaviate/client6/v1/api/collections/query/Where.java | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java index 11eb8770..bcf4bd59 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java @@ -77,7 +77,8 @@ public final SELF consistencyLevel(ConsistencyLevel consistencyLevel) { * {@code gte}, {@code like}, etc. * Subsequent calls to {@link #where} aggregate with an AND operator. * - * @see {@link Where} + *

+ * See: {@link Where} */ public final SELF where(Where where) { this.where = this.where == null ? where : Where.and(this.where, where); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/ById.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/ById.java index 8a64a0e5..f2e37f6a 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/ById.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/ById.java @@ -15,7 +15,7 @@ public record ById( List returnReferences, List returnMetadata) implements QueryOperator { - private static final String ID_PROPERTY = "_id"; + static final String ID_PROPERTY = "_id"; public static ById of(String uuid) { return of(uuid, ObjectBuilder.identity()); @@ -67,7 +67,7 @@ public ById build() { @Override public void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { - var where = Where.property(ID_PROPERTY).eq(uuid); + var where = Where.uuid().eq(uuid); var filter = WeaviateProtoBase.Filters.newBuilder(); where.appendTo(filter); req.setFilters(filter); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java index 418600e7..0542db68 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java @@ -97,7 +97,7 @@ public static Where or(List operands) { // -------------------------------------------------------------------------- public static WhereBuilder uuid() { - return property("_id"); + return property(ById.ID_PROPERTY); } public static WhereBuilder property(String property) {