Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
<assertj-core.version>3.27.4</assertj-core.version>
<jparams.version>1.0.4</jparams.version>
<mockito.version>5.19.0</mockito.version>
<slf4j.version>2.0.17</slf4j.version>
<slf4j.version>1.7.36</slf4j.version>
<logback.version>1.5.18</logback.version>
<mock-server.version>5.14.0</mock-server.version>
<jackson.version>2.19.2</jackson.version>
Expand Down
67 changes: 67 additions & 0 deletions src/it/java/io/weaviate/integration/SearchITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -257,6 +258,72 @@ public void testFetchObjectsWithFilters() throws IOException {

}

@Test
public void testFetchObjectsWithSort() throws Exception {
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())
.as("value asc")
.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())
.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
public void testBm25() throws IOException, InterruptedException, ExecutionException {
var nsWords = ns("Words");
Expand Down
Original file line number Diff line number Diff line change
@@ -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> sortBy) implements QueryOperator {

public static FetchObjects of(Function<Builder, ObjectBuilder<FetchObjects>> 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<Builder, FetchObjects> {
private final List<SortBy> sortBy = new ArrayList<>();

public Builder sort(SortBy... sortBy) {
return sort(Arrays.asList(sortBy));
}

public Builder sort(List<SortBy> sortBy) {
this.sortBy.addAll(sortBy);
return this;
}

@Override
public final FetchObjects build() {
Expand All @@ -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()));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.weaviate.client6.v1.api.collections.query;

import java.util.List;

public record SortBy(List<String> path, boolean ascending) {
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);
}

public SortBy desc() {
return new SortBy(path, false);
}
}