Skip to content

Commit 8c94cd1

Browse files
committed
test(broken): use Array and List<?> filters
Server returns error: UNKNOWN: explorer: get class: concurrentTargetVector Search): explorer: get class: vector search: object vector search at index things: s hard things_JlFtZoNmwIqT: build inverted filter allow list: nested query: nested cla use at pos 1: expected value to be string, got '[]string'
1 parent b767535 commit 8c94cd1

File tree

4 files changed

+59
-19
lines changed

4 files changed

+59
-19
lines changed

src/main/java/io/weaviate/client/v1/experimental/Batcher.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ public void add(T properties, String id, Float[] vector) {
7373

7474
void append(ObjectsBatcher batcher) {
7575
for ($WeaviateObject<T> object : objects) {
76-
7776
batcher.withObject(WeaviateObject.builder()
7877
.className(cls.getSimpleName() + "s")
7978
.vector(object.vector)

src/main/java/io/weaviate/client/v1/experimental/SearchOptions.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import org.apache.commons.lang3.StringUtils;
88

9+
import com.google.protobuf.util.JsonFormat;
10+
911
import io.weaviate.client.grpc.protocol.v1.WeaviateProtoBase.Filters;
1012
import io.weaviate.client.grpc.protocol.v1.WeaviateProtoSearchGet.MetadataRequest;
1113
import io.weaviate.client.grpc.protocol.v1.WeaviateProtoSearchGet.PropertiesRequest;
@@ -43,6 +45,10 @@ void append(SearchRequest.Builder search) {
4345
Filters.Builder filters = Filters.newBuilder();
4446
where.append(filters);
4547
search.setFilters(filters);
48+
try {
49+
System.out.println(JsonFormat.printer().print(filters));
50+
} catch (Exception e) {
51+
}
4652
}
4753

4854
if (!returnMetadata.isEmpty()) {

src/main/java/io/weaviate/client/v1/experimental/Where.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,21 @@ static Operand fromObject(Object value) {
127127
return new $Number((Number) value);
128128
} else if (value instanceof Date) {
129129
return new $Date((Date) value);
130+
} else if (value instanceof String[]) {
131+
return new $TextArray((String[]) value);
132+
} else if (value instanceof Boolean[]) {
133+
return new $BooleanArray((Boolean[]) value);
134+
} else if (value instanceof Integer[]) {
135+
return new $IntegerArray((Integer[]) value);
136+
} else if (value instanceof Number[]) {
137+
return new $NumberArray((Number[]) value);
138+
} else if (value instanceof Date[]) {
139+
return new $DateArray((Date[]) value);
130140
} else if (value instanceof List) {
131-
assert ((List<?>) value).isEmpty() : "list must not be empty";
141+
if (((List<?>) value).isEmpty()) {
142+
throw new IllegalArgumentException(
143+
"Filter with non-reifiable type (List<T>) cannot be empty, use an array instead");
144+
}
132145

133146
Object first = ((List<?>) value).get(0);
134147
if (first instanceof String) {
@@ -143,7 +156,8 @@ static Operand fromObject(Object value) {
143156
return new $DateArray((List<Date>) value);
144157
}
145158
}
146-
throw new IllegalArgumentException("value must be either of String, Boolean, Date, Integer, Number, List");
159+
throw new IllegalArgumentException(
160+
"value must be either of String, Boolean, Date, Integer, Number, Array/List of these types");
147161
}
148162

149163
// Equal

src/test/java/io/weaviate/integration/client/grpc/GRPCBenchTest.java

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import java.time.Instant;
88
import java.util.ArrayList;
9+
import java.util.Arrays;
910
import java.util.Date;
1011
import java.util.HashMap;
1112
import java.util.List;
@@ -58,11 +59,14 @@ public class GRPCBenchTest {
5859
private static final Date NOW = Date.from(Instant.now());
5960

6061
private static final int K = 10;
61-
private static final Map<String, Object> filters = new HashMap<String, Object>() {
62+
private static final String[] notIngredients = { "ketchup", "mayo" };
63+
private static final Map<String, Object> notEqualFilters = new HashMap<String, Object>() {
6264
{
63-
this.put("title", "SomeThing");
64-
this.put("price", 8);
65-
this.put("bestBefore", DateUtils.addDays(NOW, 5));
65+
// this.put("title", "SomeThing");
66+
// this.put("price", 8);
67+
// this.put("bestBefore", DateUtils.addDays(NOW, 5));
68+
this.put("ingredientsList", Arrays.asList(notIngredients));
69+
this.put("ingredientsArray", notIngredients);
6670
}
6771
};
6872

@@ -102,10 +106,10 @@ public void before() {
102106
assertTrue(writeORM(testData), "loaded test data successfully");
103107
}
104108

105-
@Test
109+
// @Test
106110
public void testGraphQL() {
107111
bench("GraphQL", () -> {
108-
int count = searchKNN(queryVector, K, filters, builder -> {
112+
int count = searchKNN(queryVector, K, notEqualFilters, builder -> {
109113
Result<GraphQLResponse> result = client
110114
.graphQL().raw()
111115
.withQuery(builder.build().buildQuery())
@@ -121,10 +125,10 @@ public void testGraphQL() {
121125
}, WARMUP_ROUNDS, BENCHMARK_ROUNDS);
122126
}
123127

124-
@Test
128+
// @Test
125129
public void testGRPC() {
126130
bench("GRPC", () -> {
127-
int count = searchKNN(queryVector, K, filters, builder -> {
131+
int count = searchKNN(queryVector, K, notEqualFilters, builder -> {
128132
SearchResult<Map<String, Object>> result = client
129133
.gRPC().raw()
130134
.withSearch(builder.build().buildSearchRequest())
@@ -137,7 +141,7 @@ public void testGRPC() {
137141
}, WARMUP_ROUNDS, BENCHMARK_ROUNDS);
138142
}
139143

140-
@Test
144+
// @Test
141145
public void testNewClient() {
142146
final float[] vector = ArrayUtils.toPrimitive(queryVector);
143147
final Collection<Map> things = client.collections.use(className, Map.class);
@@ -160,9 +164,14 @@ public static class Thing {
160164
public String title;
161165
public Double price;
162166
public Date bestBefore;
167+
168+
public String[] ingredientsArray = {};
169+
// WARN: this is to test filtering with List<?> values. Creating List<?>
170+
// properties is not supported in this version.
171+
public String[] ingredientsList = {};
163172
}
164173

165-
@Test
174+
// @Test
166175
public void testORMClient() {
167176
final float[] vector = ArrayUtils.toPrimitive(queryVector);
168177
bench("GRPC.orm", () -> {
@@ -190,19 +199,19 @@ public void testORMClientMapFilter() {
190199
vector,
191200
opt -> opt
192201
.limit(K)
193-
.where(Where.and(filters, Where.Operator.NOT_EQUAL)) // Constructed from a Map<String, Object>!
202+
.where(Where.and(notEqualFilters, Where.Operator.NOT_EQUAL)) // Constructed from a Map<String, Object>!
194203
.returnProperties(returnProperties)
195204
.returnMetadata(MetadataField.ID, MetadataField.VECTOR, MetadataField.DISTANCE));
196205

197206
int count = countGRPC(result);
198207
assertEquals(K, count, String.format("must return K=%d results", K));
199208

200209
// Check that filtering works
201-
assertFalse(result.objects.stream().anyMatch(obj -> obj.properties.title.equals(filters.get("title"))),
202-
"expected title to not be in result set: " + filters.get("title"));
210+
assertFalse(result.objects.stream().anyMatch(obj -> obj.properties.title.equals(notEqualFilters.get("title"))),
211+
"expected title to not be in result set: " + notEqualFilters.get("title"));
203212

204-
assertFalse(result.objects.stream().anyMatch(obj -> obj.properties.price.equals(filters.get("price"))),
205-
"expected price to not be in result set: " + filters.get("price"));
213+
assertFalse(result.objects.stream().anyMatch(obj -> obj.properties.price.equals(notEqualFilters.get("price"))),
214+
"expected price to not be in result set: " + notEqualFilters.get("price"));
206215
}, WARMUP_ROUNDS, BENCHMARK_ROUNDS);
207216
}
208217

@@ -336,6 +345,7 @@ private boolean write(List<Float[]> embeddings) {
336345
int count = 0;
337346
for (Float[] e : embeddings) {
338347
int i = count++;
348+
String[] ingr = mixIngredients();
339349
batcher.withObject(WeaviateObject.builder()
340350
.className(className)
341351
.vector(e)
@@ -344,6 +354,8 @@ private boolean write(List<Float[]> embeddings) {
344354
this.put("title", "Thing-" + String.valueOf(i));
345355
this.put("price", i);
346356
this.put("bestBefore", DateFormatUtils.format(DateUtils.addDays(NOW, i), "yyyy-MM-dd'T'HH:mm:ssZZZZZ"));
357+
this.put("ingredientsArray", ingr);
358+
this.put("ingredientsList", ingr);
347359
}
348360
})
349361
// .id(getUuid(e)) -> use generated UUID
@@ -358,6 +370,7 @@ private boolean write(List<Float[]> embeddings) {
358370
/** writeORM creates {@link Thing} objects and inserts them in a batch. */
359371
private boolean writeORM(List<Float[]> embeddings) {
360372
try (Batcher<Thing> batch = client.datax.batch(Thing.class)) {
373+
String[] ingr = mixIngredients();
361374
return batch.insert(b -> {
362375
int i = 0;
363376
for (Float[] e : embeddings) {
@@ -367,14 +380,22 @@ private boolean writeORM(List<Float[]> embeddings) {
367380

368381
// Notice how the ORM is able to handle a raw Date object
369382
// and convert it to the correct format behind the scenes.
370-
/* bestBefore */ DateUtils.addDays(NOW, i));
383+
/* bestBefore */ DateUtils.addDays(NOW, i),
384+
/* ingredientsArray */ ingr,
385+
/* ingredientsList */ ingr);
371386
b.add(thing, e);
372387
i++;
373388
}
374389
});
375390
}
376391
}
377392

393+
/** Utility for creating random combinations of ingredients for test data. */
394+
private String[] mixIngredients() {
395+
return Arrays.stream(new String[] { "milk", "honey", "butter" })
396+
.filter(x -> rand.nextBoolean()).toArray(String[]::new);
397+
}
398+
378399
private static Float[] genVector(int length, float origin, float bound) {
379400
Float[] vec = new Float[length];
380401
for (int i = 0; i < length; i++) {

0 commit comments

Comments
 (0)