|
1 | 1 | package io.weaviate.integration; |
2 | 2 |
|
3 | 3 | import java.io.IOException; |
| 4 | +import java.time.OffsetDateTime; |
4 | 5 | import java.util.Collections; |
5 | 6 | import java.util.Comparator; |
6 | 7 | import java.util.HashMap; |
|
13 | 14 | import org.assertj.core.api.InstanceOfAssertFactories; |
14 | 15 | import org.junit.BeforeClass; |
15 | 16 | import org.junit.ClassRule; |
| 17 | +import org.junit.Ignore; |
16 | 18 | import org.junit.Test; |
17 | 19 | import org.junit.rules.TestRule; |
18 | 20 |
|
|
29 | 31 | import io.weaviate.client6.v1.api.collections.generate.GenerativeObject; |
30 | 32 | import io.weaviate.client6.v1.api.collections.generate.TaskOutput; |
31 | 33 | import io.weaviate.client6.v1.api.collections.generative.DummyGenerative; |
| 34 | +import io.weaviate.client6.v1.api.collections.query.Filter; |
32 | 35 | import io.weaviate.client6.v1.api.collections.query.GroupBy; |
33 | 36 | import io.weaviate.client6.v1.api.collections.query.Metadata; |
34 | 37 | import io.weaviate.client6.v1.api.collections.query.QueryMetadata; |
35 | 38 | import io.weaviate.client6.v1.api.collections.query.QueryResponseGroup; |
36 | 39 | import io.weaviate.client6.v1.api.collections.query.ReadWeaviateObject; |
37 | 40 | import io.weaviate.client6.v1.api.collections.query.SortBy; |
38 | 41 | import io.weaviate.client6.v1.api.collections.query.Target; |
39 | | -import io.weaviate.client6.v1.api.collections.query.Filter; |
40 | 42 | import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw; |
41 | 43 | import io.weaviate.client6.v1.api.collections.vectorindex.MultiVector; |
42 | 44 | import io.weaviate.containers.Container; |
@@ -671,4 +673,97 @@ public void testGenerative_bm25_groupBy() throws IOException { |
671 | 673 | .extracting(TaskOutput::text, InstanceOfAssertFactories.STRING) |
672 | 674 | .isNotBlank(); |
673 | 675 | } |
| 676 | + |
| 677 | + @Test |
| 678 | + public void test_filterIsNull() throws IOException { |
| 679 | + // Arrange |
| 680 | + var nsNulls = ns("Nulls"); |
| 681 | + |
| 682 | + var nulls = client.collections.create(nsNulls, |
| 683 | + c -> c |
| 684 | + .invertedIndex(idx -> idx.indexNulls(true)) |
| 685 | + .properties(Property.text("never"))); |
| 686 | + |
| 687 | + var inserted = nulls.data.insertMany(Map.of(), Map.of("never", "notNull")); |
| 688 | + Assertions.assertThat(inserted.errors()).isEmpty(); |
| 689 | + |
| 690 | + // Act |
| 691 | + var isNull = nulls.query.fetchObjects(q -> q.filters(Filter.property("never").isNull())); |
| 692 | + var isNotNull = nulls.query.fetchObjects(q -> q.filters(Filter.property("never").isNotNull())); |
| 693 | + |
| 694 | + // Assert |
| 695 | + var isNull_1 = Assertions.assertThat(isNull.objects()) |
| 696 | + .as("objects WHERE never IS NULL") |
| 697 | + .hasSize(1).first().actual(); |
| 698 | + var isNotNull_1 = Assertions.assertThat(isNotNull.objects()) |
| 699 | + .as("objects WHERE never IS NOT NULL") |
| 700 | + .hasSize(1).first().actual(); |
| 701 | + Assertions.assertThat(isNull_1).isNotEqualTo(isNotNull_1); |
| 702 | + } |
| 703 | + |
| 704 | + @Test |
| 705 | + public void test_filterCreateUpdateTime() throws IOException { |
| 706 | + // Arrange |
| 707 | + var now = OffsetDateTime.now().minusHours(1); |
| 708 | + var nsCounter = ns("Counter"); |
| 709 | + |
| 710 | + var counter = client.collections.create(nsCounter, |
| 711 | + c -> c |
| 712 | + .invertedIndex(idx -> idx.indexTimestamps(true)) |
| 713 | + .properties(Property.integer("count"))); |
| 714 | + |
| 715 | + counter.data.insert(Map.of("count", 0)); |
| 716 | + |
| 717 | + // Act |
| 718 | + var beforeNow = counter.query.fetchObjects(q -> q.filters(Filter.createdAt().lt(now))); |
| 719 | + var afterNow = counter.query.fetchObjects(q -> q.filters(Filter.createdAt().gt(now))); |
| 720 | + |
| 721 | + // Assert |
| 722 | + Assertions.assertThat(beforeNow.objects()).isEmpty(); |
| 723 | + Assertions.assertThat(afterNow.objects()).hasSize(1); |
| 724 | + } |
| 725 | + |
| 726 | + @Test |
| 727 | + public void teset_filterPropertyLength() throws IOException { |
| 728 | + // Arrange |
| 729 | + var nsStrings = ns("Strings"); |
| 730 | + |
| 731 | + var strings = client.collections.create(nsStrings, c -> c |
| 732 | + .invertedIndex(idx -> idx.indexPropertyLength(true)) |
| 733 | + .properties(Property.text("letters"))); |
| 734 | + strings.data.insertMany(Map.of("letters", "abc"), Map.of("letters", "abcd"), Map.of("letters", "a")); |
| 735 | + |
| 736 | + // Act |
| 737 | + var got = strings.query.fetchObjects(q -> q.filters(Filter.propertyLen("letters").gte(3))); |
| 738 | + |
| 739 | + // Assertions |
| 740 | + Assertions.assertThat(got.objects()).hasSize(2); |
| 741 | + } |
| 742 | + |
| 743 | + /** |
| 744 | + * Ensure the client respects server's configuration for max gRPC size: |
| 745 | + * we create a server with 1-byte message size and try to send a large payload |
| 746 | + * there. If the channel is configured correctly, it will refuse to send it. |
| 747 | + */ |
| 748 | + @Test |
| 749 | + @Ignore("Exception thrown by gRPC transport causes a deadlock") |
| 750 | + public void test_maxGrpcMessageSize() throws Exception { |
| 751 | + var w = Weaviate.custom().withGrpcMaxMessageSize(1).build(); |
| 752 | + var nsHugeVectors = ns("HugeVectors"); |
| 753 | + |
| 754 | + try (final var _client = w.getClient()) { |
| 755 | + var huge = _client.collections.create(nsHugeVectors, c -> c |
| 756 | + .vectorConfig(VectorConfig.selfProvided())); |
| 757 | + |
| 758 | + final var vector = randomVector(5000, -.01f, .01f); |
| 759 | + final WeaviateObject<Map<String, Object>, Reference, ObjectMetadata> hugeObject = WeaviateObject.of(obj -> obj |
| 760 | + .metadata(ObjectMetadata.of(m -> m |
| 761 | + .vectors(Vectors.of(vector))))); |
| 762 | + |
| 763 | + Assertions.assertThatThrownBy(() -> { |
| 764 | + // insertMany to route this request through gRPC. |
| 765 | + huge.data.insertMany(hugeObject); |
| 766 | + }).isInstanceOf(io.grpc.StatusRuntimeException.class); |
| 767 | + } |
| 768 | + } |
674 | 769 | } |
0 commit comments