From ae0ba06799402e292e6f38f32c65696c071f3256 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 11 Jun 2025 15:32:58 +0200 Subject: [PATCH 1/3] feat: implement query filters with Where.and / Where.or Add client.collections.fetchObjects to run queries without a dedicated search operator. Update PropertyBuilder interface to handle null values. --- .../io/weaviate/integration/SearchITest.java | 35 + .../aggregate/AggregateRequest.java | 2 +- .../query/AbstractQueryClient.java | 19 + .../collections/query/BaseQueryOptions.java | 40 +- .../collections/query/ConsistencyLevel.java | 20 + .../api/collections/query/FetchObjects.java | 30 + .../api/collections/query/QueryRequest.java | 9 +- .../query/WeaviateObjectUnmarshaler.java | 0 .../v1/api/collections/query/Where.java | 771 ++++++++++++++++++ .../api/collections/query/WhereOperand.java | 11 + .../client6/v1/internal/orm/MapBuilder.java | 5 + .../v1/internal/orm/PropertiesBuilder.java | 2 + 12 files changed, 933 insertions(+), 11 deletions(-) create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/FetchObjects.java delete mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateObjectUnmarshaler.java create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/WhereOperand.java diff --git a/src/it/java/io/weaviate/integration/SearchITest.java b/src/it/java/io/weaviate/integration/SearchITest.java index 17679a5bc..01b216dee 100644 --- a/src/it/java/io/weaviate/integration/SearchITest.java +++ b/src/it/java/io/weaviate/integration/SearchITest.java @@ -23,6 +23,7 @@ import io.weaviate.client6.v1.api.collections.query.GroupBy; import io.weaviate.client6.v1.api.collections.query.MetadataField; import io.weaviate.client6.v1.api.collections.query.QueryResponseGroup; +import io.weaviate.client6.v1.api.collections.query.Where; import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw; import io.weaviate.client6.v1.api.collections.vectorizers.Img2VecNeuralVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.NoneVectorizer; @@ -220,4 +221,38 @@ public void testNearImage() throws IOException { .extracting(WeaviateObject::properties, InstanceOfAssertFactories.MAP) .extractingByKey("breed").isEqualTo("ragdoll"); } + + @Test + public void testFetchObjectsWithFilters() throws IOException { + var nsHats = ns("Hats"); + + client.collections.create(nsHats, + collection -> collection + .properties( + Property.text("colour"), + Property.integer("size"))); + + var hats = client.collections.use(nsHats); + + /* blackHat */ hats.data.insert(Map.of("colour", "black", "size", 6)); + var redHat = hats.data.insert(Map.of("colour", "red", "size", 5)); + var greenHat = hats.data.insert(Map.of("colour", "green", "size", 1)); + var hugeHat = hats.data.insert(Map.of("colour", "orange", "size", 40)); + + var got = hats.query.fetchObjects( + query -> query.where( + Where.or( + Where.property("colour").eq("orange"), + Where.and( + Where.property("size").gte(1), + Where.property("size").lt(6))))); + + Assertions.assertThat(got.objects()) + .extracting(hat -> hat.metadata().uuid()) + .containsOnly( + redHat.metadata().uuid(), + greenHat.metadata().uuid(), + hugeHat.metadata().uuid()); + + } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AggregateRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AggregateRequest.java index a70e4170c..79a84505f 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AggregateRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AggregateRequest.java @@ -60,7 +60,7 @@ static Rpc(property, groupBy.getText()); } else { - assert false : "branch not covered"; + assert false : "(aggregate) branch not covered"; } var properties = unmarshalAggregation(result.getAggregations()); 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 abdca72a3..cdfe8cad4 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 @@ -37,6 +37,25 @@ protected final Optional optionalFirst(List objects) { return objects.isEmpty() ? Optional.empty() : Optional.ofNullable(objects.get(0)); } + // Object queries ----------------------------------------------------------- + + public ResponseT fetchObjects(Function> fn) { + return fetchObjects(FetchObjects.of(fn)); + } + + public ResponseT fetchObjects(FetchObjects query) { + return performRequest(query); + } + + public GroupedResponseT fetchObjects(Function> fn, + GroupBy groupBy) { + return fetchObjects(FetchObjects.of(fn), groupBy); + } + + public GroupedResponseT fetchObjects(FetchObjects 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/BaseQueryOptions.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java index 495957d76..7c2a403e2 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 @@ -7,6 +7,7 @@ import org.apache.commons.lang3.StringUtils; import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; public record BaseQueryOptions( @@ -14,7 +15,8 @@ public record BaseQueryOptions( Integer offset, Integer autocut, String after, - String consistencyLevel, + ConsistencyLevel consistencyLevel, + Where where, List returnProperties, List returnReferences, List returnMetadata) { @@ -26,6 +28,7 @@ private BaseQueryOptions(Builder, T> builder.autocut, builder.after, builder.consistencyLevel, + builder.where, builder.returnProperties, builder.returnReferences, builder.returnMetadata); @@ -38,7 +41,8 @@ public static abstract class Builder, T extends Ob private Integer offset; private Integer autocut; private String after; - private String consistencyLevel; + private ConsistencyLevel consistencyLevel; + private Where where; private List returnProperties = new ArrayList<>(); private List returnReferences = new ArrayList<>(); private List returnMetadata = new ArrayList<>(); @@ -63,6 +67,16 @@ public final SELF after(String after) { return (SELF) this; } + public final SELF consistencyLevel(ConsistencyLevel consistencyLevel) { + this.consistencyLevel = consistencyLevel; + return (SELF) this; + } + + public final SELF where(Where where) { + this.where = where; + return (SELF) this; + } + public final SELF returnProperties(String... properties) { this.returnProperties = Arrays.asList(properties); return (SELF) this; @@ -106,20 +120,30 @@ final void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { req.setAutocut(autocut); } - if (StringUtils.isNotBlank(consistencyLevel)) { - req.setConsistencyLevelValue(Integer.valueOf(consistencyLevel)); + if (consistencyLevel != null) { + consistencyLevel.appendTo(req); + } + + if (where != null) { + var filter = WeaviateProtoBase.Filters.newBuilder(); + where.appendTo(filter); + req.setFilters(filter); } - if (!returnMetadata.isEmpty()) { - var metadata = WeaviateProtoSearchGet.MetadataRequest.newBuilder(); + var metadata = WeaviateProtoSearchGet.MetadataRequest.newBuilder(); + if (returnMetadata.isEmpty()) { + MetadataField.ID.appendTo(metadata); + } else { returnMetadata.forEach(m -> m.appendTo(metadata)); - req.setMetadata(metadata); } + req.setMetadata(metadata); if (!returnProperties.isEmpty() || !returnReferences.isEmpty()) { var properties = WeaviateProtoSearchGet.PropertiesRequest.newBuilder(); - if (!returnProperties.isEmpty()) { + if (returnProperties.isEmpty()) { + properties.setReturnAllNonrefProperties(true); + } else { properties.addAllNonRefProperties(returnProperties); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java new file mode 100644 index 000000000..27cd30221 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java @@ -0,0 +1,20 @@ +package io.weaviate.client6.v1.api.collections.query; + +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; + +public enum ConsistencyLevel { + ONE(WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE), + QUORUM(WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE), + ALL(WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE); + + private final WeaviateProtoBase.ConsistencyLevel consistencyLevel; + + ConsistencyLevel(WeaviateProtoBase.ConsistencyLevel consistencyLevel) { + this.consistencyLevel = consistencyLevel; + } + + final void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + req.setConsistencyLevel(consistencyLevel); + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/FetchObjects.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/FetchObjects.java new file mode 100644 index 000000000..7313985eb --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/FetchObjects.java @@ -0,0 +1,30 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.function.Function; + +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; + +public record FetchObjects(BaseQueryOptions common) implements SearchOperator { + + public static FetchObjects of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + public FetchObjects(Builder builder) { + this(builder.baseOptions()); + } + + public static class Builder extends BaseQueryOptions.Builder { + + @Override + public final FetchObjects build() { + return new FetchObjects(this); + } + } + + @Override + public void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + common.appendTo(req); + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java index 33c271cf5..54591d32a 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java @@ -9,6 +9,9 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.util.JsonFormat; + import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Vectors; import io.weaviate.client6.v1.api.collections.WeaviateObject; @@ -176,7 +179,9 @@ private static WeaviateObject unmarshalReferences private static void setProperty(String property, WeaviateProtoProperties.Value value, PropertiesBuilder builder) { - if (value.hasTextValue()) { + if (value.hasNullValue()) { + builder.setNull(property); + } else if (value.hasTextValue()) { builder.setText(property, value.getTextValue()); } else if (value.hasBoolValue()) { builder.setBoolean(property, value.getBoolValue()); @@ -190,7 +195,7 @@ private static void setProperty(String property, WeaviateProtoProperties.Val OffsetDateTime offsetDateTime = OffsetDateTime.parse(value.getDateValue()); builder.setDate(property, Date.from(offsetDateTime.toInstant())); } else { - assert false : "branch not covered"; + assert false : "(query) branch not covered"; } } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateObjectUnmarshaler.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateObjectUnmarshaler.java deleted file mode 100644 index e69de29bb..000000000 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 new file mode 100644 index 000000000..65379a513 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java @@ -0,0 +1,771 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase.Filters; + +public class Where implements WhereOperand { + + private enum Operator { + // Logical operators + AND("And", WeaviateProtoBase.Filters.Operator.OPERATOR_AND), + OR("Or", WeaviateProtoBase.Filters.Operator.OPERATOR_OR), + + // Comparison operators + EQUAL("Equal", WeaviateProtoBase.Filters.Operator.OPERATOR_EQUAL), + NOT_EQUAL("NotEqual", WeaviateProtoBase.Filters.Operator.OPERATOR_NOT_EQUAL), + LESS_THAN("LessThen", WeaviateProtoBase.Filters.Operator.OPERATOR_LESS_THAN), + LESS_THAN_EQUAL("LessThenEqual", WeaviateProtoBase.Filters.Operator.OPERATOR_LESS_THAN_EQUAL), + GREATER_THAN("GreaterThen", WeaviateProtoBase.Filters.Operator.OPERATOR_GREATER_THAN), + GREATER_THAN_EQUAL("GreaterThenEqual", WeaviateProtoBase.Filters.Operator.OPERATOR_GREATER_THAN_EQUAL), + LIKE("Like", WeaviateProtoBase.Filters.Operator.OPERATOR_LIKE), + CONTAINS_ANY("ContainsAny", WeaviateProtoBase.Filters.Operator.OPERATOR_CONTAINS_ANY), + CONTAINS_ALL("ContainsAll", WeaviateProtoBase.Filters.Operator.OPERATOR_CONTAINS_ALL), + WITHIN_GEO_RANGE("WithinGeoRange", WeaviateProtoBase.Filters.Operator.OPERATOR_WITHIN_GEO_RANGE); + + /** String representation for better debug logs. */ + private final String stringValue; + + /** gRPC operator value . */ + private final WeaviateProtoBase.Filters.Operator grpcValue; + + private Operator(String stringValue, WeaviateProtoBase.Filters.Operator grpcValue) { + this.stringValue = stringValue; + this.grpcValue = grpcValue; + } + + public void appendTo(Filters.Builder where) { + where.setOperator(grpcValue); + } + + @Override + public String toString() { + return stringValue; + } + } + + private final Operator operator; + private final List operands; + + @SafeVarargs + private Where(Operator operator, WhereOperand... operands) { + this(operator, Arrays.asList(operands)); + } + + private Where(Operator operator, List operands) { + this.operator = operator; + this.operands = operands; + } + + @Override + public boolean isEmpty() { + // Guard against Where.and(Where.or(), Where.and()) situation. + return operands.isEmpty() + || operands.stream().allMatch(operator -> operator.isEmpty()); + } + + // Logical operators return a complete operand. + // -------------------------------------------------------------------------- + public static Where and(WhereOperand... operands) { + return new Where(Operator.AND, operands); + } + + public static Where and(List operands) { + return new Where(Operator.AND, operands); + } + + public static Where or(WhereOperand... operands) { + return new Where(Operator.OR, operands); + } + + public static Where or(List operands) { + return new Where(Operator.OR, operands); + } + + // Comparison operators return fluid builder. + // -------------------------------------------------------------------------- + + public static WhereBuilder property(String property) { + return new WhereBuilder(new PathOperand(property)); + } + + public static WhereBuilder reference(String... path) { + return new WhereBuilder(new PathOperand(path)); + } + + public static class WhereBuilder { + private final WhereOperand left; + + private WhereBuilder(WhereOperand left) { + this.left = left; + } + + // Equal + // ------------------------------------------------------------------------ + public Where eq(String value) { + return new Where(Operator.EQUAL, left, new TextOperand(value)); + } + + public Where eq(String... values) { + return new Where(Operator.EQUAL, left, new TextArrayOperand(values)); + } + + public Where eq(Boolean value) { + return new Where(Operator.EQUAL, left, new BooleanOperand(value)); + } + + public Where eq(Boolean... values) { + return new Where(Operator.EQUAL, left, new BooleanArrayOperand(values)); + } + + public Where eq(Integer value) { + return new Where(Operator.EQUAL, left, new IntegerOperand(value)); + } + + public Where eq(Integer... values) { + return new Where(Operator.EQUAL, left, new IntegerArrayOperand(values)); + } + + public Where eq(Number value) { + return new Where(Operator.EQUAL, left, new NumberOperand(value.doubleValue())); + } + + public Where eq(Number... values) { + return new Where(Operator.EQUAL, left, new NumberArrayOperand(values)); + } + + public Where eq(Date value) { + return new Where(Operator.EQUAL, left, new DateOperand(value)); + } + + public Where eq(Date... values) { + return new Where(Operator.EQUAL, left, new DateArrayOperand(values)); + } + + public Where eq(Object value) { + return new Where(Operator.EQUAL, left, fromObject(value)); + } + + // NotEqual + // ------------------------------------------------------------------------ + public Where ne(String value) { + return new Where(Operator.NOT_EQUAL, left, new TextOperand(value)); + } + + public Where ne(String... values) { + return new Where(Operator.NOT_EQUAL, left, new TextArrayOperand(values)); + } + + public Where ne(Boolean value) { + return new Where(Operator.NOT_EQUAL, left, new BooleanOperand(value)); + } + + public Where ne(Boolean... values) { + return new Where(Operator.NOT_EQUAL, left, new BooleanArrayOperand(values)); + } + + public Where ne(Integer value) { + return new Where(Operator.NOT_EQUAL, left, new IntegerOperand(value)); + } + + public Where ne(Integer... values) { + return new Where(Operator.NOT_EQUAL, left, new IntegerArrayOperand(values)); + } + + public Where ne(Number value) { + return new Where(Operator.NOT_EQUAL, left, new NumberOperand(value.doubleValue())); + } + + public Where ne(Number... values) { + return new Where(Operator.NOT_EQUAL, left, new NumberArrayOperand(values)); + } + + public Where ne(Date value) { + return new Where(Operator.NOT_EQUAL, left, new DateOperand(value)); + } + + public Where ne(Date... values) { + return new Where(Operator.NOT_EQUAL, left, new DateArrayOperand(values)); + } + + public Where ne(Object value) { + return new Where(Operator.NOT_EQUAL, left, fromObject(value)); + } + + // LessThan + // ------------------------------------------------------------------------ + public Where lt(String value) { + return new Where(Operator.LESS_THAN, left, new TextOperand(value)); + } + + public Where lt(String... values) { + return new Where(Operator.LESS_THAN, left, new TextArrayOperand(values)); + } + + public Where lt(Boolean value) { + return new Where(Operator.LESS_THAN, left, new BooleanOperand(value)); + } + + public Where lt(Boolean... values) { + return new Where(Operator.LESS_THAN, left, new BooleanArrayOperand(values)); + } + + public Where lt(Integer value) { + return new Where(Operator.LESS_THAN, left, new IntegerOperand(value)); + } + + public Where lt(Integer... values) { + return new Where(Operator.LESS_THAN, left, new IntegerArrayOperand(values)); + } + + public Where lt(Number value) { + return new Where(Operator.LESS_THAN, left, new NumberOperand(value.doubleValue())); + } + + public Where lt(Number... values) { + return new Where(Operator.LESS_THAN, left, new NumberArrayOperand(values)); + } + + public Where lt(Date value) { + return new Where(Operator.LESS_THAN, left, new DateOperand(value)); + } + + public Where lt(Date... values) { + return new Where(Operator.LESS_THAN, left, new DateArrayOperand(values)); + } + + public Where lt(Object value) { + return new Where(Operator.LESS_THAN, left, fromObject(value)); + } + + // LessThanEqual + // ------------------------------------------------------------------------ + public Where lte(String value) { + return new Where(Operator.LESS_THAN_EQUAL, left, new TextOperand(value)); + } + + public Where lte(String... values) { + return new Where(Operator.LESS_THAN_EQUAL, left, new TextArrayOperand(values)); + } + + public Where lte(Boolean value) { + return new Where(Operator.LESS_THAN_EQUAL, left, new BooleanOperand(value)); + } + + public Where lte(Boolean... values) { + return new Where(Operator.LESS_THAN_EQUAL, left, new BooleanArrayOperand(values)); + } + + public Where lte(Integer value) { + return new Where(Operator.LESS_THAN_EQUAL, left, new IntegerOperand(value)); + } + + public Where lte(Integer... values) { + return new Where(Operator.LESS_THAN_EQUAL, left, new IntegerArrayOperand(values)); + } + + public Where lte(Number value) { + return new Where(Operator.LESS_THAN_EQUAL, left, new NumberOperand(value.doubleValue())); + } + + public Where lte(Number... values) { + return new Where(Operator.LESS_THAN_EQUAL, left, new NumberArrayOperand(values)); + } + + public Where lte(Date value) { + return new Where(Operator.LESS_THAN_EQUAL, left, new DateOperand(value)); + } + + public Where lte(Date... values) { + return new Where(Operator.LESS_THAN_EQUAL, left, new DateArrayOperand(values)); + } + + public Where lte(Object value) { + return new Where(Operator.LESS_THAN_EQUAL, left, fromObject(value)); + } + + // GreaterThan + // ------------------------------------------------------------------------ + public Where gt(String value) { + return new Where(Operator.GREATER_THAN, left, new TextOperand(value)); + } + + public Where gt(String... values) { + return new Where(Operator.GREATER_THAN, left, new TextArrayOperand(values)); + } + + public Where gt(Boolean value) { + return new Where(Operator.GREATER_THAN, left, new BooleanOperand(value)); + } + + public Where gt(Boolean... values) { + return new Where(Operator.GREATER_THAN, left, new BooleanArrayOperand(values)); + } + + public Where gt(Integer value) { + return new Where(Operator.GREATER_THAN, left, new IntegerOperand(value)); + } + + public Where gt(Integer... values) { + return new Where(Operator.GREATER_THAN, left, new IntegerArrayOperand(values)); + } + + public Where gt(Number value) { + return new Where(Operator.GREATER_THAN, left, new NumberOperand(value.doubleValue())); + } + + public Where gt(Number... values) { + return new Where(Operator.GREATER_THAN, left, new NumberArrayOperand(values)); + } + + public Where gt(Date value) { + return new Where(Operator.GREATER_THAN, left, new DateOperand(value)); + } + + public Where gt(Date... values) { + return new Where(Operator.GREATER_THAN, left, new DateArrayOperand(values)); + } + + public Where gt(Object value) { + return new Where(Operator.GREATER_THAN, left, fromObject(value)); + } + + // GreaterThanEqual + // ------------------------------------------------------------------------ + public Where gte(String value) { + return new Where(Operator.GREATER_THAN_EQUAL, left, new TextOperand(value)); + } + + public Where gte(String... values) { + return new Where(Operator.GREATER_THAN_EQUAL, left, new TextArrayOperand(values)); + } + + public Where gte(Boolean value) { + return new Where(Operator.GREATER_THAN_EQUAL, left, new BooleanOperand(value)); + } + + public Where gte(Boolean... values) { + return new Where(Operator.GREATER_THAN_EQUAL, left, new BooleanArrayOperand(values)); + } + + public Where gte(Integer value) { + return new Where(Operator.GREATER_THAN_EQUAL, left, new IntegerOperand(value)); + } + + public Where gte(Integer... values) { + return new Where(Operator.GREATER_THAN_EQUAL, left, new IntegerArrayOperand(values)); + } + + public Where gte(Number value) { + return new Where(Operator.GREATER_THAN_EQUAL, left, new NumberOperand(value.doubleValue())); + } + + public Where gte(Number... values) { + return new Where(Operator.GREATER_THAN_EQUAL, left, new NumberArrayOperand(values)); + } + + public Where gte(Date value) { + return new Where(Operator.GREATER_THAN_EQUAL, left, new DateOperand(value)); + } + + public Where gte(Date... values) { + return new Where(Operator.GREATER_THAN_EQUAL, left, new DateArrayOperand(values)); + } + + public Where gte(Object value) { + return new Where(Operator.GREATER_THAN_EQUAL, left, fromObject(value)); + } + + // Like + // ------------------------------------------------------------------------ + public Where like(String value) { + return new Where(Operator.LIKE, left, new TextOperand(value)); + } + + public Where like(String... values) { + return new Where(Operator.LIKE, left, new TextArrayOperand(values)); + } + + public Where like(Boolean value) { + return new Where(Operator.LIKE, left, new BooleanOperand(value)); + } + + public Where like(Boolean... values) { + return new Where(Operator.LIKE, left, new BooleanArrayOperand(values)); + } + + public Where like(Integer value) { + return new Where(Operator.LIKE, left, new IntegerOperand(value)); + } + + public Where like(Integer... values) { + return new Where(Operator.LIKE, left, new IntegerArrayOperand(values)); + } + + public Where like(Number value) { + return new Where(Operator.LIKE, left, new NumberOperand(value.doubleValue())); + } + + public Where like(Number... values) { + return new Where(Operator.LIKE, left, new NumberArrayOperand(values)); + } + + public Where like(Date value) { + return new Where(Operator.LIKE, left, new DateOperand(value)); + } + + public Where like(Date... values) { + return new Where(Operator.LIKE, left, new DateArrayOperand(values)); + } + + public Where like(Object value) { + return new Where(Operator.LIKE, left, fromObject(value)); + } + + // ContainsAny + // ------------------------------------------------------------------------ + public Where containsAny(String value) { + return new Where(Operator.CONTAINS_ANY, left, new TextOperand(value)); + } + + public Where containsAny(String... values) { + return new Where(Operator.CONTAINS_ANY, left, new TextArrayOperand(values)); + } + + public Where containsAny(Boolean... values) { + return new Where(Operator.CONTAINS_ANY, left, new BooleanArrayOperand(values)); + } + + public Where containsAny(Integer... values) { + return new Where(Operator.CONTAINS_ANY, left, new IntegerArrayOperand(values)); + } + + public Where containsAny(Number... values) { + return new Where(Operator.CONTAINS_ANY, left, new NumberArrayOperand(values)); + } + + public Where containsAny(Date... values) { + return new Where(Operator.CONTAINS_ANY, left, new DateArrayOperand(values)); + } + + // ContainsAll + // ------------------------------------------------------------------------ + public Where containsAll(String value) { + return new Where(Operator.CONTAINS_ALL, left, new TextOperand(value)); + } + + public Where containsAll(String... values) { + return new Where(Operator.CONTAINS_ALL, left, new TextArrayOperand(values)); + } + + public Where containsAll(Boolean... values) { + return new Where(Operator.CONTAINS_ALL, left, new BooleanArrayOperand(values)); + } + + public Where containsAll(Integer... values) { + return new Where(Operator.CONTAINS_ALL, left, new IntegerArrayOperand(values)); + } + + public Where containsAll(Number... values) { + return new Where(Operator.CONTAINS_ALL, left, new NumberArrayOperand(values)); + } + + public Where containsAll(Date... values) { + return new Where(Operator.CONTAINS_ALL, left, new DateArrayOperand(values)); + } + + // WithinGeoRange + // ------------------------------------------------------------------------ + public Where withinGeoRange(float lat, float lon, float maxDistance) { + return new Where(Operator.WITHIN_GEO_RANGE, left, new GeoRangeOperand(lat, lon, maxDistance)); + } + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + if (isEmpty()) { + return; + } + switch (operands.size()) { + case 0: + return; + case 1: // no need for operator + operands.get(0).appendTo(where); + return; + default: + if (operator.equals(Operator.AND) || operator.equals(Operator.OR)) { + operands.forEach(op -> { + Filters.Builder nested = Filters.newBuilder(); + op.appendTo(nested); + where.addFilters(nested); + }); + } else { + // Comparison operators: eq, gt, lt, like, etc. + operands.forEach(op -> op.appendTo(where)); + } + } + operator.appendTo(where); + } + + @SuppressWarnings("unchecked") + static WhereOperand fromObject(Object value) { + if (value instanceof String) { + return new TextOperand((String) value); + } else if (value instanceof Boolean) { + return new BooleanOperand((Boolean) value); + } else if (value instanceof Integer) { + return new IntegerOperand((Integer) value); + } else if (value instanceof Number) { + return new NumberOperand((Number) value); + } else if (value instanceof Date) { + return new DateOperand((Date) value); + } else if (value instanceof String[]) { + return new TextArrayOperand((String[]) value); + } else if (value instanceof Boolean[]) { + return new BooleanArrayOperand((Boolean[]) value); + } else if (value instanceof Integer[]) { + return new IntegerArrayOperand((Integer[]) value); + } else if (value instanceof Number[]) { + return new NumberArrayOperand((Number[]) value); + } else if (value instanceof Date[]) { + return new DateArrayOperand((Date[]) value); + } else if (value instanceof List) { + if (((List) value).isEmpty()) { + throw new IllegalArgumentException( + "Filter with non-reifiable type (List) cannot be empty, use an array instead"); + } + + Object first = ((List) value).get(0); + if (first instanceof String) { + return new TextArrayOperand((List) value); + } else if (first instanceof Boolean) { + return new BooleanArrayOperand((List) value); + } else if (first instanceof Integer) { + return new IntegerArrayOperand((List) value); + } else if (first instanceof Number) { + return new NumberArrayOperand((List) value); + } else if (first instanceof Date) { + return new DateArrayOperand((List) value); + } + } + throw new IllegalArgumentException( + "value must be either of String, Boolean, Date, Integer, Number, Array/List of these types"); + } + + private static class PathOperand implements WhereOperand { + private final List path; + + private PathOperand(List path) { + this.path = path; + } + + @SafeVarargs + private PathOperand(String... path) { + this(Arrays.asList(path)); + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + // "on" is deprecated, but the current proto doesn"t have "path". + if (!path.isEmpty()) { + where.addOn(path.get(0)); + } + // FIXME: no way to reference objects rn? + } + } + + private static class TextOperand implements WhereOperand { + private final String value; + + private TextOperand(String value) { + this.value = value; + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + where.setValueText(value); + } + } + + private static class TextArrayOperand implements WhereOperand { + private final List values; + + private TextArrayOperand(List values) { + this.values = values; + } + + @SafeVarargs + private TextArrayOperand(String... values) { + this(Arrays.asList(values)); + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + where.setValueTextArray(WeaviateProtoBase.TextArray.newBuilder().addAllValues(values)); + } + } + + private static class BooleanOperand implements WhereOperand { + private final Boolean value; + + private BooleanOperand(Boolean value) { + this.value = value; + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + where.setValueBoolean(value); + } + } + + private static class BooleanArrayOperand implements WhereOperand { + private final List values; + + private BooleanArrayOperand(List values) { + this.values = values; + } + + @SafeVarargs + private BooleanArrayOperand(Boolean... values) { + this(Arrays.asList(values)); + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + where.setValueBooleanArray(WeaviateProtoBase.BooleanArray.newBuilder().addAllValues(values)); + } + } + + private static class IntegerOperand implements WhereOperand { + private final Integer value; + + private IntegerOperand(Integer value) { + this.value = value; + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + where.setValueInt(value); + } + } + + private static class IntegerArrayOperand implements WhereOperand { + private final List values; + + private IntegerArrayOperand(List values) { + this.values = values; + } + + @SafeVarargs + private IntegerArrayOperand(Integer... values) { + this(Arrays.asList(values)); + } + + private List toLongs() { + return values.stream().map(Integer::longValue).toList(); + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + where.setValueIntArray(WeaviateProtoBase.IntArray.newBuilder().addAllValues(toLongs())); + } + } + + private static class NumberOperand implements WhereOperand { + private final Number value; + + private NumberOperand(Number value) { + this.value = value; + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + where.setValueNumber(value.doubleValue()); + } + } + + private static class NumberArrayOperand implements WhereOperand { + private final List values; + + private NumberArrayOperand(List values) { + this.values = values; + } + + @SafeVarargs + private NumberArrayOperand(Number... values) { + this(Arrays.asList(values)); + } + + private List toDoubles() { + return values.stream().map(Number::doubleValue).toList(); + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + where.setValueNumberArray(WeaviateProtoBase.NumberArray.newBuilder().addAllValues(toDoubles())); + } + } + + private static class DateOperand implements WhereOperand { + private final Date value; + + private DateOperand(Date value) { + this.value = value; + } + + private static String format(Date date) { + return DateFormatUtils.format(date, "yyyy-MM-dd'T'HH:mm:ssZZZZZ"); + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + where.setValueText(format(value)); + } + } + + private static class DateArrayOperand implements WhereOperand { + private final List values; + + private DateArrayOperand(List values) { + this.values = values; + } + + @SafeVarargs + private DateArrayOperand(Date... values) { + this(Arrays.asList(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())); + } + } + + private static class GeoRangeOperand implements WhereOperand { + private final Float lat; + private final Float lon; + private final Float distance; + + private GeoRangeOperand(Float lat, Float lon, Float distance) { + this.lat = lat; + this.lon = lon; + this.distance = distance; + } + + @Override + public void appendTo(WeaviateProtoBase.Filters.Builder where) { + where.setValueGeo(WeaviateProtoBase.GeoCoordinatesFilter.newBuilder() + .setLatitude(lat).setLongitude(lon).setDistance(distance)); + } + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/WhereOperand.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/WhereOperand.java new file mode 100644 index 000000000..40b46456a --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/WhereOperand.java @@ -0,0 +1,11 @@ +package io.weaviate.client6.v1.api.collections.query; + +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase; + +public interface WhereOperand { + void appendTo(WeaviateProtoBase.Filters.Builder where); + + default boolean isEmpty() { + return false; + } +} diff --git a/src/main/java/io/weaviate/client6/v1/internal/orm/MapBuilder.java b/src/main/java/io/weaviate/client6/v1/internal/orm/MapBuilder.java index 857f471a1..c45bd57a4 100644 --- a/src/main/java/io/weaviate/client6/v1/internal/orm/MapBuilder.java +++ b/src/main/java/io/weaviate/client6/v1/internal/orm/MapBuilder.java @@ -7,6 +7,11 @@ public class MapBuilder implements PropertiesBuilder> { private final Map properties = new HashMap<>(); + @Override + public void setNull(String property) { + properties.put(property, null); + } + @Override public void setText(String property, String value) { properties.put(property, value); diff --git a/src/main/java/io/weaviate/client6/v1/internal/orm/PropertiesBuilder.java b/src/main/java/io/weaviate/client6/v1/internal/orm/PropertiesBuilder.java index ddef1ab18..0d88d385c 100644 --- a/src/main/java/io/weaviate/client6/v1/internal/orm/PropertiesBuilder.java +++ b/src/main/java/io/weaviate/client6/v1/internal/orm/PropertiesBuilder.java @@ -3,6 +3,8 @@ import java.util.Date; public interface PropertiesBuilder { + void setNull(String property); + void setText(String property, String value); void setBoolean(String property, Boolean value); From fd1f5ec472b08bfe7ee969b2964184f3ded9261f Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 11 Jun 2025 16:22:24 +0200 Subject: [PATCH 2/3] feat: remove useless parameters from the ById query --- .../io/weaviate/integration/DataITest.java | 3 +- .../v1/api/collections/query/ById.java | 78 +++++++++++++------ 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/it/java/io/weaviate/integration/DataITest.java b/src/it/java/io/weaviate/integration/DataITest.java index 1f29861aa..2879e71b1 100644 --- a/src/it/java/io/weaviate/integration/DataITest.java +++ b/src/it/java/io/weaviate/integration/DataITest.java @@ -13,6 +13,7 @@ import io.weaviate.client6.v1.api.collections.Property; import io.weaviate.client6.v1.api.collections.Vectors; import io.weaviate.client6.v1.api.collections.WeaviateObject; +import io.weaviate.client6.v1.api.collections.query.MetadataField; import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw; import io.weaviate.client6.v1.api.collections.vectorizers.NoneVectorizer; import io.weaviate.containers.Container; @@ -40,7 +41,7 @@ public void testCreateGetDelete() throws IOException { var object = artists.query.byId(id, query -> query .returnProperties("name") - .includeVector(true)); + .returnMetadata(MetadataField.ID, MetadataField.VECTOR)); Assertions.assertThat(object) .as("object exists after insert").get() 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 9d250d58d..e914ab58c 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 @@ -1,19 +1,19 @@ 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; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase; -import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase.Filters.Operator; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; public record ById( String uuid, - boolean includeVector, - List includeVectors, - BaseQueryOptions common) implements SearchOperator { + List returnProperties, + List returnReferences, + List returnMetadata) implements SearchOperator { private static final String ID_PROPERTY = "_id"; @@ -26,49 +26,77 @@ public static ById of(String uuid, Function> fn) { } public ById(Builder builder) { - this(builder.uuid, builder.includeVector, builder.includeVectors, builder.baseOptions()); + this(builder.uuid, + builder.returnProperties, + builder.returnReferences, + builder.returnMetadata); } - public static class Builder extends BaseQueryOptions.Builder { + public static class Builder implements ObjectBuilder { // Required query parameters. private final String uuid; - private boolean includeVector = false; - private List includeVectors = new ArrayList<>(); + private List returnProperties = new ArrayList<>(); + private List returnReferences = new ArrayList<>(); + private List returnMetadata = new ArrayList<>(); public Builder(String uuid) { this.uuid = uuid; } - public final Builder includeVector(boolean include) { - this.includeVector = include; + public final Builder returnProperties(String... properties) { + this.returnProperties = Arrays.asList(properties); + return this; + } + + public final Builder returnReferences(QueryReference... references) { + this.returnReferences = Arrays.asList(references); + return this; + } + + public final Builder returnMetadata(Metadata... metadata) { + this.returnMetadata = Arrays.asList(metadata); return this; } @Override - public final ById build() { + public ById build() { return new ById(this); } } @Override public void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { - common.appendTo(req); - - // Always request UUID back in this request. - var metadata = WeaviateProtoSearchGet.MetadataRequest.newBuilder() - .setUuid(true); - if (includeVector) { - metadata.setVector(true); - } else if (!includeVectors.isEmpty()) { - metadata.addAllVectors(includeVectors); + var where = Where.property(ID_PROPERTY).eq(uuid); + var filter = WeaviateProtoBase.Filters.newBuilder(); + where.appendTo(filter); + req.setFilters(filter); + + var metadata = WeaviateProtoSearchGet.MetadataRequest.newBuilder(); + if (returnMetadata.isEmpty()) { + MetadataField.ID.appendTo(metadata); + } else { + returnMetadata.forEach(m -> m.appendTo(metadata)); } req.setMetadata(metadata); - req.setFilters(WeaviateProtoBase.Filters.newBuilder() - .setTarget(WeaviateProtoBase.FilterTarget.newBuilder() - .setProperty(ID_PROPERTY)) - .setValueText(uuid) - .setOperator(Operator.OPERATOR_EQUAL)); + if (!returnProperties.isEmpty() || !returnReferences.isEmpty()) { + var properties = WeaviateProtoSearchGet.PropertiesRequest.newBuilder(); + + if (returnProperties.isEmpty()) { + properties.setReturnAllNonrefProperties(true); + } else { + properties.addAllNonRefProperties(returnProperties); + } + + if (!returnReferences.isEmpty()) { + returnReferences.forEach(r -> { + var ref = WeaviateProtoSearchGet.RefPropertiesRequest.newBuilder(); + r.appendTo(ref); + properties.addRefProperties(ref); + }); + } + req.setProperties(properties); + } } } From a64f299048817bb098f889fca72b34ca86b3d6e8 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 11 Jun 2025 16:31:00 +0200 Subject: [PATCH 3/3] refactor: expose metadata fields as static Metadata members Makes for a more concise query syntax. --- src/it/java/io/weaviate/integration/DataITest.java | 4 ++-- src/it/java/io/weaviate/integration/ReferencesITest.java | 8 ++++---- src/it/java/io/weaviate/integration/SearchITest.java | 4 ++-- .../v1/api/collections/query/BaseQueryOptions.java | 2 +- .../weaviate/client6/v1/api/collections/query/ById.java | 2 +- .../client6/v1/api/collections/query/Metadata.java | 5 ++++- .../client6/v1/api/collections/query/MetadataField.java | 6 +++++- .../client6/v1/api/collections/query/QueryRequest.java | 3 --- 8 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/it/java/io/weaviate/integration/DataITest.java b/src/it/java/io/weaviate/integration/DataITest.java index 2879e71b1..e7db1664b 100644 --- a/src/it/java/io/weaviate/integration/DataITest.java +++ b/src/it/java/io/weaviate/integration/DataITest.java @@ -13,7 +13,7 @@ import io.weaviate.client6.v1.api.collections.Property; import io.weaviate.client6.v1.api.collections.Vectors; import io.weaviate.client6.v1.api.collections.WeaviateObject; -import io.weaviate.client6.v1.api.collections.query.MetadataField; +import io.weaviate.client6.v1.api.collections.query.Metadata; import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw; import io.weaviate.client6.v1.api.collections.vectorizers.NoneVectorizer; import io.weaviate.containers.Container; @@ -41,7 +41,7 @@ public void testCreateGetDelete() throws IOException { var object = artists.query.byId(id, query -> query .returnProperties("name") - .returnMetadata(MetadataField.ID, MetadataField.VECTOR)); + .returnMetadata(Metadata.ID, Metadata.VECTOR)); Assertions.assertThat(object) .as("object exists after insert").get() diff --git a/src/it/java/io/weaviate/integration/ReferencesITest.java b/src/it/java/io/weaviate/integration/ReferencesITest.java index 519319e64..68aa7b623 100644 --- a/src/it/java/io/weaviate/integration/ReferencesITest.java +++ b/src/it/java/io/weaviate/integration/ReferencesITest.java @@ -16,7 +16,7 @@ import io.weaviate.client6.v1.api.collections.ReferenceProperty; 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.MetadataField; +import io.weaviate.client6.v1.api.collections.query.Metadata; import io.weaviate.client6.v1.api.collections.query.QueryReference; import io.weaviate.containers.Container; @@ -95,9 +95,9 @@ public void testReferences() throws IOException { var gotAlex = artists.query.byId(alex.metadata().uuid(), opt -> opt.returnReferences( QueryReference.multi("hasAwards", nsOscar, - ref -> ref.returnMetadata(MetadataField.ID)), + ref -> ref.returnMetadata(Metadata.ID)), QueryReference.multi("hasAwards", nsGrammy, - ref -> ref.returnMetadata(MetadataField.ID)))); + ref -> ref.returnMetadata(Metadata.ID)))); Assertions.assertThat(gotAlex).get() .as("Artists: fetch by id including hasAwards references") @@ -166,7 +166,7 @@ public void testNestedReferences() throws IOException { .returnReferences( QueryReference.single("presentedBy", r -> r.returnProperties("ceo"))) // Grammy ID - .returnMetadata(MetadataField.ID)))); + .returnMetadata(Metadata.ID)))); Assertions.assertThat(gotAlex).get() .as("Artists: fetch by id including nested references") diff --git a/src/it/java/io/weaviate/integration/SearchITest.java b/src/it/java/io/weaviate/integration/SearchITest.java index 01b216dee..73c4d0375 100644 --- a/src/it/java/io/weaviate/integration/SearchITest.java +++ b/src/it/java/io/weaviate/integration/SearchITest.java @@ -21,7 +21,7 @@ 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; -import io.weaviate.client6.v1.api.collections.query.MetadataField; +import io.weaviate.client6.v1.api.collections.query.Metadata; import io.weaviate.client6.v1.api.collections.query.QueryResponseGroup; import io.weaviate.client6.v1.api.collections.query.Where; import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw; @@ -69,7 +69,7 @@ public void testNearVector() { opt -> opt .distance(2f) .limit(3) - .returnMetadata(MetadataField.DISTANCE)); + .returnMetadata(Metadata.DISTANCE)); Assertions.assertThat(result.objects()).hasSize(3); float maxDistance = Collections.max(result.objects(), 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 7c2a403e2..0ac29d7e9 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 @@ -132,7 +132,7 @@ final void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { var metadata = WeaviateProtoSearchGet.MetadataRequest.newBuilder(); if (returnMetadata.isEmpty()) { - MetadataField.ID.appendTo(metadata); + Metadata.ID.appendTo(metadata); } else { returnMetadata.forEach(m -> m.appendTo(metadata)); } 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 e914ab58c..2740c598e 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 @@ -74,7 +74,7 @@ public void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { var metadata = WeaviateProtoSearchGet.MetadataRequest.newBuilder(); if (returnMetadata.isEmpty()) { - MetadataField.ID.appendTo(metadata); + Metadata.ID.appendTo(metadata); } else { returnMetadata.forEach(m -> m.appendTo(metadata)); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/Metadata.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/Metadata.java index 05df0730e..62396632f 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/Metadata.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/Metadata.java @@ -10,5 +10,8 @@ public interface Metadata { void appendTo(WeaviateProtoSearchGet.MetadataRequest.Builder metadata); - // TODO: export all possible metadata as static members + public static final Metadata ID = MetadataField.ID; + public static final Metadata VECTOR = MetadataField.VECTOR; + public static final Metadata DISTANCE = MetadataField.DISTANCE; + public static final Metadata CERTAINTY = MetadataField.CERTAINTY; } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/MetadataField.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/MetadataField.java index c6d67b20a..3f2fcdf82 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/MetadataField.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/MetadataField.java @@ -8,7 +8,8 @@ public enum MetadataField implements Metadata { ID, VECTOR, - DISTANCE; + DISTANCE, + CERTAINTY; public void appendTo(WeaviateProtoSearchGet.MetadataRequest.Builder metadata) { switch (this) { @@ -21,6 +22,9 @@ public void appendTo(WeaviateProtoSearchGet.MetadataRequest.Builder metadata) { case DISTANCE: metadata.setDistance(true); break; + case CERTAINTY: + metadata.setCertainty(true); + break; } } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java index 54591d32a..fd40952e5 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java @@ -9,9 +9,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.util.JsonFormat; - import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Vectors; import io.weaviate.client6.v1.api.collections.WeaviateObject;