Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
74 changes: 70 additions & 4 deletions src/it/java/io/weaviate/integration/SearchITest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.weaviate.integration;

import java.io.IOException;
import java.time.OffsetDateTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
Expand Down Expand Up @@ -31,13 +32,13 @@
import io.weaviate.client6.v1.api.collections.generate.GenerativeObject;
import io.weaviate.client6.v1.api.collections.generate.TaskOutput;
import io.weaviate.client6.v1.api.collections.generative.DummyGenerative;
import io.weaviate.client6.v1.api.collections.query.Filter;
import io.weaviate.client6.v1.api.collections.query.GroupBy;
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.Target;
import io.weaviate.client6.v1.api.collections.query.Filter;
import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw;
import io.weaviate.client6.v1.api.collections.vectorindex.MultiVector;
import io.weaviate.containers.Container;
Expand Down Expand Up @@ -609,9 +610,9 @@ public void testGenerative_bm25() throws IOException {
.hasSize(2)
.allSatisfy(obj -> {
Assertions.assertThat(obj).as("uuid shorthand")
.returns(obj.uuid(), GenerativeObject::uuid);
.returns(obj.uuid(), GenerativeObject::uuid);
Assertions.assertThat(obj).as("vectors shorthand")
.returns(obj.vectors(), GenerativeObject::vectors);
.returns(obj.vectors(), GenerativeObject::vectors);
})
.extracting(GenerativeObject::generative)
.allSatisfy(generated -> {
Expand Down Expand Up @@ -675,6 +676,72 @@ public void testGenerative_bm25_groupBy() throws IOException {
.isNotBlank();
}

@Test
public void test_filterIsNull() throws IOException {
// Arrange
var nsNulls = ns("Nulls");

var nulls = client.collections.create(nsNulls,
c -> c
.invertedIndex(idx -> idx.indexNulls(true))
.properties(Property.text("never")));

var inserted = nulls.data.insertMany(Map.of(), Map.of("never", "notNull"));
Assertions.assertThat(inserted.errors()).isEmpty();

// Act
var isNull = nulls.query.fetchObjects(q -> q.filters(Filter.property("never").isNull()));
var isNotNull = nulls.query.fetchObjects(q -> q.filters(Filter.property("never").isNotNull()));

// Assert
var isNull_1 = Assertions.assertThat(isNull.objects())
.as("objects WHERE never IS NULL")
.hasSize(1).first().actual();
var isNotNull_1 = Assertions.assertThat(isNotNull.objects())
.as("objects WHERE never IS NOT NULL")
.hasSize(1).first().actual();
Assertions.assertThat(isNull_1).isNotEqualTo(isNotNull_1);
}

@Test
public void test_filterCreateUpdateTime() throws IOException {
// Arrange
var now = OffsetDateTime.now().minusHours(1);
var nsCounter = ns("Counter");

var counter = client.collections.create(nsCounter,
c -> c
.invertedIndex(idx -> idx.indexTimestamps(true))
.properties(Property.integer("count")));

counter.data.insert(Map.of("count", 0));

// Act
var beforeNow = counter.query.fetchObjects(q -> q.filters(Filter.createdAt().lt(now)));
var afterNow = counter.query.fetchObjects(q -> q.filters(Filter.createdAt().gt(now)));

// Assert
Assertions.assertThat(beforeNow.objects()).isEmpty();
Assertions.assertThat(afterNow.objects()).hasSize(1);
}

@Test
public void teset_filterPropertyLength() throws IOException {
// Arrange
var nsStrings = ns("Strings");

var strings = client.collections.create(nsStrings, c -> c
.invertedIndex(idx -> idx.indexPropertyLength(true))
.properties(Property.text("letters")));
strings.data.insertMany(Map.of("letters", "abc"), Map.of("letters", "abcd"), Map.of("letters", "a"));

// Act
var got = strings.query.fetchObjects(q -> q.filters(Filter.propertyLen("letters").gte(3)));

// Assertions
Assertions.assertThat(got.objects()).hasSize(2);
}

/**
* Ensure the client respects server's configuration for max gRPC size:
* we create a server with 1-byte message size and try to send a large payload
Expand All @@ -700,6 +767,5 @@ public void test_maxGrpcMessageSize() throws Exception {
huge.data.insertMany(hugeObject);
}).isInstanceOf(io.grpc.StatusRuntimeException.class);
}
System.out.println("here?");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public record BaseQueryOptions(
List<Metadata> returnMetadata,
List<String> includeVectors) {

static final String ID_PROPERTY = "_id";
static final String CREATION_TIME_PROPERTY = "_creationTimeUnix";
static final String LAST_UPDATE_TIME_PROPERTY = "_lastUpdateTimeUnix";

private <T extends Object> BaseQueryOptions(Builder<? extends Builder<?, T>, T> builder) {
this(
builder.limit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ public record FetchObjectById(
List<Metadata> returnMetadata,
List<String> includeVectors) implements QueryOperator {

static final String ID_PROPERTY = "_id";

public static FetchObjectById of(String uuid) {
return of(uuid, ObjectBuilder.identity());
}
Expand Down
135 changes: 121 additions & 14 deletions src/main/java/io/weaviate/client6/v1/api/collections/query/Filter.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ private enum Operator {
// 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("LessThan", 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),
GREATER_THAN("GreaterThan", WeaviateProtoBase.Filters.Operator.OPERATOR_GREATER_THAN),
GREATER_THAN_EQUAL("GreaterThanEqual", WeaviateProtoBase.Filters.Operator.OPERATOR_GREATER_THAN_EQUAL),
IS_NULL("IsNull", WeaviateProtoBase.Filters.Operator.OPERATOR_IS_NULL),
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),
Expand Down Expand Up @@ -109,18 +110,28 @@ public Filter not() {
// --------------------------------------------------------------------------

/** Filter by object UUID. */
public static FilterBuilder uuid() {
return property(FetchObjectById.ID_PROPERTY);
public static UuidProperty uuid() {
return new UuidProperty();
}

/** Filter by object creation time. */
public static DateProperty createdAt() {
return new DateProperty(BaseQueryOptions.CREATION_TIME_PROPERTY);
}

/** Filter by object last update time. */
public static DateProperty lastUpdatedAt() {
return new DateProperty(BaseQueryOptions.LAST_UPDATE_TIME_PROPERTY);
}

/** Filter by object property. */
public static FilterBuilder property(String property) {
return new FilterBuilder(new PathOperand(property));
return new FilterBuilder(new PathOperand(false, property));
}

/** Filter by a property of the referenced object. */
public static FilterBuilder reference(String... path) {
return new FilterBuilder(new PathOperand(path));
/** Filter by object property's length. */
public static FilterBuilder propertyLen(String property) {
return new FilterBuilder(new PathOperand(true, property));
}

public static class FilterBuilder {
Expand Down Expand Up @@ -422,6 +433,20 @@ public Filter gte(Object value) {
return new Filter(Operator.GREATER_THAN_EQUAL, left, fromObject(value));
}

// IsNull
// ------------------------------------------------------------------------
public Filter isNull() {
return isNull(true);
}

public Filter isNotNull() {
return isNull(false);
}

public Filter isNull(boolean isNull) {
return new Filter(Operator.IS_NULL, left, new BooleanOperand(isNull));
}

// Like
// ------------------------------------------------------------------------
public Filter like(String value) {
Expand Down Expand Up @@ -596,20 +621,26 @@ static FilterOperand fromObject(Object value) {

private static class PathOperand implements FilterOperand {
private final List<String> path;
private final boolean length;

private PathOperand(List<String> path) {
private PathOperand(boolean length, List<String> path) {
this.path = path;
this.length = length;
}

private PathOperand(String... path) {
this(Arrays.asList(path));
private PathOperand(boolean length, String... path) {
this(length, Arrays.asList(path));
}

@Override
public void appendTo(WeaviateProtoBase.Filters.Builder filter) {
// "on" is deprecated, but the current proto doesn't have "path".
if (!path.isEmpty()) {
filter.addOn(path.get(0));
var property = path.get(0);
if (length) {
property = "len(" + property + ")";
}
filter.setTarget(WeaviateProtoBase.FilterTarget.newBuilder()
.setProperty(property));
}
// FIXME: no way to reference objects rn?
}
Expand All @@ -620,6 +651,82 @@ public String toString() {
}
}

public static class UuidProperty extends PathOperand {
private UuidProperty() {
super(false, BaseQueryOptions.ID_PROPERTY);
}

public Filter eq(String value) {
return new Filter(Operator.EQUAL, this, new TextOperand(value));
}

public Filter ne(String value) {
return new Filter(Operator.NOT_EQUAL, this, new TextOperand(value));
}

public Filter gt(String value) {
return new Filter(Operator.GREATER_THAN, this, new TextOperand(value));
}

public Filter gte(String value) {
return new Filter(Operator.GREATER_THAN_EQUAL, this, new TextOperand(value));
}

public Filter lt(String value) {
return new Filter(Operator.LESS_THAN, this, new TextOperand(value));
}

public Filter lte(String value) {
return new Filter(Operator.LESS_THAN_EQUAL, this, new TextOperand(value));
}

public Filter containsAny(String... values) {
return new Filter(Operator.CONTAINS_ANY, this, new TextArrayOperand(values));
}

public Filter containsNone(String... values) {
return new Filter(Operator.CONTAINS_NONE, this, new TextArrayOperand(values));
}
}

public static class DateProperty extends PathOperand {
private DateProperty(String propertyName) {
super(false, propertyName);
}

public Filter eq(OffsetDateTime value) {
return new Filter(Operator.EQUAL, this, new DateOperand(value));
}

public Filter ne(OffsetDateTime value) {
return new Filter(Operator.NOT_EQUAL, this, new DateOperand(value));
}

public Filter gt(OffsetDateTime value) {
return new Filter(Operator.GREATER_THAN, this, new DateOperand(value));
}

public Filter gte(OffsetDateTime value) {
return new Filter(Operator.GREATER_THAN_EQUAL, this, new DateOperand(value));
}

public Filter lt(OffsetDateTime value) {
return new Filter(Operator.LESS_THAN, this, new DateOperand(value));
}

public Filter lte(OffsetDateTime value) {
return new Filter(Operator.LESS_THAN_EQUAL, this, new DateOperand(value));
}

public Filter containsAny(OffsetDateTime... values) {
return new Filter(Operator.CONTAINS_ANY, this, new DateArrayOperand(values));
}

public Filter containsNone(OffsetDateTime... values) {
return new Filter(Operator.CONTAINS_NONE, this, new DateArrayOperand(values));
}
}

private static class TextOperand implements FilterOperand {
private final String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static SortBy property(String property) {
* @see #desc() to sort in descending order.
*/
public static SortBy uuid() {
return property(FetchObjectById.ID_PROPERTY);
return property(BaseQueryOptions.ID_PROPERTY);
}

/**
Expand Down