From 87529414f8d9201951f13ffda50a067a4fecab01 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Tue, 9 Sep 2025 18:46:28 +0200 Subject: [PATCH 1/4] chore: add SortBy to fetch objects --- .../io/weaviate/integration/SearchITest.java | 36 +++++++++++++++++++ .../api/collections/query/FetchObjects.java | 23 ++++++++++-- .../v1/api/collections/query/SortBy.java | 17 +++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java diff --git a/src/it/java/io/weaviate/integration/SearchITest.java b/src/it/java/io/weaviate/integration/SearchITest.java index 057501844..f9361303f 100644 --- a/src/it/java/io/weaviate/integration/SearchITest.java +++ b/src/it/java/io/weaviate/integration/SearchITest.java @@ -29,6 +29,7 @@ import io.weaviate.client6.v1.api.collections.query.Metadata; import io.weaviate.client6.v1.api.collections.query.QueryMetadata; import io.weaviate.client6.v1.api.collections.query.QueryResponseGroup; +import io.weaviate.client6.v1.api.collections.query.SortBy; import io.weaviate.client6.v1.api.collections.query.Where; import io.weaviate.containers.Container; import io.weaviate.containers.Container.ContainerGroup; @@ -257,6 +258,41 @@ public void testFetchObjectsWithFilters() throws IOException { } + @Test + public void testFetchObjectsWithSort() throws IOException { + var nsNumbers = ns("Numbers"); + + // Arrange + client.collections.create(nsNumbers, + c -> c.properties(Property.integer("value"))); + + var numbers = client.collections.use(nsNumbers); + + var one = numbers.data.insert(Map.of("value", 1L)); + var two = numbers.data.insert(Map.of("value", 2L)); + var three = numbers.data.insert(Map.of("value", 3L)); + + // Act: sort ascending + var asc = numbers.query.fetchObjects( + q -> q.sort(SortBy.property("value"))); + + Assertions.assertThat(asc.objects()) + .hasSize(3) + .extracting(WeaviateObject::properties) + .extracting(object -> object.get("value")) + .containsExactly(1L, 2L, 3L); + + // Act: sort descending + var desc = numbers.query.fetchObjects( + q -> q.sort(SortBy.property("value").desc())); + + Assertions.assertThat(desc.objects()) + .hasSize(3) + .extracting(WeaviateObject::properties) + .extracting(object -> object.get("value")) + .containsExactly(3L, 2L, 1L); + } + @Test public void testBm25() throws IOException, InterruptedException, ExecutionException { var nsWords = ns("Words"); 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 index af55b4ce7..160007749 100644 --- 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 @@ -1,21 +1,34 @@ 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.WeaviateProtoSearchGet; -public record FetchObjects(BaseQueryOptions common) implements QueryOperator { +public record FetchObjects(BaseQueryOptions common, List sortBy) implements QueryOperator { public static FetchObjects of(Function> fn) { return fn.apply(new Builder()).build(); } public FetchObjects(Builder builder) { - this(builder.baseOptions()); + this(builder.baseOptions(), builder.sortBy); } public static class Builder extends BaseQueryOptions.Builder { + private final List sortBy = new ArrayList<>(); + + public Builder sort(SortBy... sortBy) { + return sort(Arrays.asList(sortBy)); + } + + public Builder sort(List sortBy) { + this.sortBy.addAll(sortBy); + return this; + } @Override public final FetchObjects build() { @@ -26,5 +39,11 @@ public final FetchObjects build() { @Override public void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { common.appendTo(req); + + for (final var sort : sortBy) { + req.addSortBy(WeaviateProtoSearchGet.SortBy.newBuilder() + .addAllPath(sort.path()) + .setAscending(sort.ascending())); + } } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java new file mode 100644 index 000000000..adb8ace0e --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java @@ -0,0 +1,17 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.List; + +public record SortBy(List path, boolean ascending) { + public static SortBy property(String property) { + return new SortBy(List.of(property), true); + } + + public SortBy asc() { + return new SortBy(path, true); + } + + public SortBy desc() { + return new SortBy(path, false); + } +} From 653237f3258b4ac7be990bc390ca42cb4ad17566 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Tue, 9 Sep 2025 19:00:48 +0200 Subject: [PATCH 2/4] feat: add SortBy.creationTime/lastUpdateTime --- .../io/weaviate/integration/SearchITest.java | 33 ++++++++++++++++++- .../v1/api/collections/query/SortBy.java | 8 +++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/it/java/io/weaviate/integration/SearchITest.java b/src/it/java/io/weaviate/integration/SearchITest.java index f9361303f..f7b64ac08 100644 --- a/src/it/java/io/weaviate/integration/SearchITest.java +++ b/src/it/java/io/weaviate/integration/SearchITest.java @@ -259,7 +259,7 @@ public void testFetchObjectsWithFilters() throws IOException { } @Test - public void testFetchObjectsWithSort() throws IOException { + public void testFetchObjectsWithSort() throws Exception { var nsNumbers = ns("Numbers"); // Arrange @@ -277,6 +277,7 @@ public void testFetchObjectsWithSort() throws IOException { q -> q.sort(SortBy.property("value"))); Assertions.assertThat(asc.objects()) + .as("value asc") .hasSize(3) .extracting(WeaviateObject::properties) .extracting(object -> object.get("value")) @@ -287,10 +288,40 @@ public void testFetchObjectsWithSort() throws IOException { q -> q.sort(SortBy.property("value").desc())); Assertions.assertThat(desc.objects()) + .as("value desc") .hasSize(3) .extracting(WeaviateObject::properties) .extracting(object -> object.get("value")) .containsExactly(3L, 2L, 1L); + + // Act: sort by creation time asc + var created = numbers.query.fetchObjects( + q -> q.sort(SortBy.creationTime())); + + Assertions.assertThat(created.objects()) + .as("create time asc") + .hasSize(3) + .extracting(WeaviateObject::uuid) + .containsExactly(one.uuid(), two.uuid(), three.uuid()); + + // Act: sort by updated time desc + numbers.data.update(one.uuid(), upd -> upd.properties(Map.of("value", -1L))); + Thread.sleep(10); + numbers.data.update(two.uuid(), upd -> upd.properties(Map.of("value", -2L))); + Thread.sleep(10); + numbers.data.update(three.uuid(), upd -> upd.properties(Map.of("value", -3L))); + + var updated = numbers.query.fetchObjects( + q -> q.sort( + // Both sort operators imply ordering 3-2-1 + SortBy.lastUpdateTime().desc(), + SortBy.property("value").asc())); + + Assertions.assertThat(updated.objects()) + .as("last update time desc + value asc") + .hasSize(3) + .extracting(WeaviateObject::uuid) + .containsExactly(three.uuid(), two.uuid(), one.uuid()); } @Test diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java index adb8ace0e..95f438cf4 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java @@ -7,6 +7,14 @@ public static SortBy property(String property) { return new SortBy(List.of(property), true); } + public static SortBy creationTime() { + return property("_creationTimeUnix"); + } + + public static SortBy lastUpdateTime() { + return property("_lastUpdateTimeUnix"); + } + public SortBy asc() { return new SortBy(path, true); } From a29ec19508dff783e775ec1a38a8b27c4c2b49ae Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Mon, 8 Sep 2025 11:11:12 +0200 Subject: [PATCH 3/4] chore: use the same SLF4J version as surefire uses --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 32a819d49..8340230c2 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ 3.27.4 1.0.4 5.19.0 - 2.0.17 + 1.7.36 1.5.18 5.14.0 2.19.2 From 137444097fcf0c1c406107a18902c9e60f154f1d Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Fri, 12 Sep 2025 14:20:44 +0200 Subject: [PATCH 4/4] chore: document SortBy usage --- .../api/collections/query/FetchObjects.java | 20 +++++++++++ .../v1/api/collections/query/SortBy.java | 35 +++++++++++++++++++ 2 files changed, 55 insertions(+) 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 index 160007749..e132497df 100644 --- 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 @@ -21,10 +21,30 @@ public FetchObjects(Builder builder) { public static class Builder extends BaseQueryOptions.Builder { private final List sortBy = new ArrayList<>(); + /** + * Sort query results. Default sorted order is ascending, use + * {@link SortBy#desc} to reverse it. + * + *
{@code
+     * sort(SortBy.property("age"), SortBy.creationTime().desc());
+     * }
+ * + * @param sortBy A list of sort-by clauses in the order + * they should be applied. + * @return This builder. + */ public Builder sort(SortBy... sortBy) { return sort(Arrays.asList(sortBy)); } + /** + * Sort query results. Default sorted order is ascending, use + * {@link SortBy#desc} to reverse it. + * + * @param sortBy A list of sort-by clauses in the order + * they should be applied. + * @return This builder. + */ public Builder sort(List sortBy) { this.sortBy.addAll(sortBy); return this; diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java index 95f438cf4..6c9d38179 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/SortBy.java @@ -3,22 +3,57 @@ import java.util.List; public record SortBy(List path, boolean ascending) { + /** + * Sort by object property. Ascending order by default. + * + * @see #desc() to sort in descending order. + */ public static SortBy property(String property) { return new SortBy(List.of(property), true); } + /** + * Sort by object creation time. Ascending order by default. + * + * @see #desc() to sort in descending order. + */ public static SortBy creationTime() { return property("_creationTimeUnix"); } + /** + * Sort by object last update time. Ascending order by default. + * + * @see #desc() to sort in descending order. + */ public static SortBy lastUpdateTime() { return property("_lastUpdateTimeUnix"); } + /** + * Sort in ascending order. + * + *

+ * Example: + * + *

{@code
+   * SortBy.property("name").asc();
+   * }
+ */ public SortBy asc() { return new SortBy(path, true); } + /** + * Sort in descending order. + * + *

+ * Example: + * + *

{@code
+   * SortBy.property("name").desc();
+   * }
+ */ public SortBy desc() { return new SortBy(path, false); }