diff --git a/pom.xml b/pom.xml
index 4339bba88..3a04bd412 100644
--- a/pom.xml
+++ b/pom.xml
@@ -349,6 +349,7 @@
${project.basedir}/src/it/java
+ ${project.basedir}/src/it/resources
diff --git a/src/it/java/io/weaviate/containers/Container.java b/src/it/java/io/weaviate/containers/Container.java
index 9ef69cfe8..2c4218a9f 100644
--- a/src/it/java/io/weaviate/containers/Container.java
+++ b/src/it/java/io/weaviate/containers/Container.java
@@ -16,6 +16,7 @@
public class Container {
public static final Weaviate WEAVIATE = Weaviate.createDefault();
public static final Contextionary CONTEXTIONARY = Contextionary.createDefault();
+ public static final Img2VecNeural IMG2VEC_NEURAL = Img2VecNeural.createDefault();
static {
startAll();
@@ -39,21 +40,23 @@ static void stopAll() {
WEAVIATE.stop();
}
- public static Group compose(Weaviate weaviate, GenericContainer>... containers) {
- return new Group(weaviate, containers);
+ public static ContainerGroup compose(Weaviate weaviate, GenericContainer>... containers) {
+ return new ContainerGroup(weaviate, containers);
}
public static TestRule asTestRule(Startable container) {
return new PerTestSuite(container);
};
- public static class Group implements Startable {
+ public static class ContainerGroup implements Startable {
private final Weaviate weaviate;
private final List> containers;
- private Group(Weaviate weaviate, GenericContainer>... containers) {
+ private ContainerGroup(Weaviate weaviate, GenericContainer>... containers) {
this.weaviate = weaviate;
this.containers = Arrays.asList(containers);
+
+ weaviate.dependsOn(containers);
setSharedNetwork();
}
@@ -63,8 +66,7 @@ public WeaviateClient getClient() {
@Override
public void start() {
- containers.forEach(GenericContainer::start);
- weaviate.start();
+ weaviate.start(); // testcontainers will resolve dependencies
}
@Override
diff --git a/src/it/java/io/weaviate/containers/Contextionary.java b/src/it/java/io/weaviate/containers/Contextionary.java
index 76ec5aefd..69abde7df 100644
--- a/src/it/java/io/weaviate/containers/Contextionary.java
+++ b/src/it/java/io/weaviate/containers/Contextionary.java
@@ -35,7 +35,7 @@ public Contextionary build() {
.withEnv("EXTENSIONS_STORAGE_ORIGIN", "http://weaviate:8080")
.withEnv("NEIGHBOR_OCCURRENCE_IGNORE_PERCENTILE", "5")
.withEnv("ENABLE_COMPOUND_SPLITTING", "'false'");
- container.withCreateContainerCmdModifier(cmd -> cmd.withHostName("contextionary"));
+ container.withCreateContainerCmdModifier(cmd -> cmd.withHostName(HOST_NAME));
return container;
}
}
diff --git a/src/it/java/io/weaviate/containers/Img2VecNeural.java b/src/it/java/io/weaviate/containers/Img2VecNeural.java
new file mode 100644
index 000000000..28bddd990
--- /dev/null
+++ b/src/it/java/io/weaviate/containers/Img2VecNeural.java
@@ -0,0 +1,38 @@
+package io.weaviate.containers;
+
+import org.testcontainers.containers.GenericContainer;
+
+public class Img2VecNeural extends GenericContainer {
+ public static final String DOCKER_IMAGE = "cr.weaviate.io/semitechnologies/img2vec-pytorch";
+ public static final String VERSION = "resnet50";
+
+ public static final String MODULE = "img2vec-neural";
+ public static final String HOST_NAME = MODULE;
+ public static final String URL = HOST_NAME + ":8080";
+
+ static Img2VecNeural createDefault() {
+ return new Builder().build();
+ }
+
+ static Img2VecNeural.Builder custom() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String versionTag;
+
+ public Builder() {
+ this.versionTag = VERSION;
+ }
+
+ public Img2VecNeural build() {
+ var container = new Img2VecNeural(DOCKER_IMAGE + ":" + versionTag);
+ container.withCreateContainerCmdModifier(cmd -> cmd.withHostName(HOST_NAME));
+ return container;
+ }
+ }
+
+ public Img2VecNeural(String image) {
+ super(image);
+ }
+}
diff --git a/src/it/java/io/weaviate/containers/Weaviate.java b/src/it/java/io/weaviate/containers/Weaviate.java
index 6126d5150..d6251c028 100644
--- a/src/it/java/io/weaviate/containers/Weaviate.java
+++ b/src/it/java/io/weaviate/containers/Weaviate.java
@@ -1,7 +1,10 @@
package io.weaviate.containers;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.testcontainers.weaviate.WeaviateContainer;
@@ -10,7 +13,7 @@
import io.weaviate.client6.WeaviateClient;
public class Weaviate extends WeaviateContainer {
- private static WeaviateClient clientInstance;
+ private WeaviateClient clientInstance;
public static final String VERSION = "1.29.0";
public static final String DOCKER_IMAGE = "semitechnologies/weaviate";
@@ -42,14 +45,14 @@ public static Weaviate.Builder custom() {
public static class Builder {
private String versionTag;
- private Set enableModules;
+ private Set enableModules = new HashSet<>();
private String defaultVectorizerModule;
- private String contextionaryUrl;
private boolean telemetry;
+ private Map environment = new HashMap<>();
+
public Builder() {
this.versionTag = VERSION;
- this.enableModules = new HashSet<>();
this.telemetry = false;
}
@@ -58,24 +61,31 @@ public Builder withVersion(String version) {
return this;
}
- public Builder addModule(String module) {
- enableModules.add(module);
+ public Builder addModules(String... modules) {
+ enableModules.addAll(Arrays.asList(modules));
return this;
}
public Builder withDefaultVectorizer(String module) {
- addModule(module);
- defaultVectorizerModule = module;
+ addModules(module);
+ environment.put("DEFAULT_VECTORIZER_MODULE", module);
return this;
}
public Builder withContextionaryUrl(String url) {
- contextionaryUrl = url;
+ addModules(Contextionary.MODULE);
+ environment.put("CONTEXTIONARY_URL", url);
+ return this;
+ }
+
+ public Builder withImageInference(String url, String module) {
+ addModules(module);
+ environment.put("IMAGE_INFERENCE_API", "http://" + url);
return this;
}
- public Builder enableTelemetry() {
- telemetry = true;
+ public Builder enableTelemetry(boolean enable) {
+ telemetry = enable;
return this;
}
@@ -83,18 +93,14 @@ public Weaviate build() {
var c = new Weaviate(DOCKER_IMAGE + ":" + versionTag);
if (!enableModules.isEmpty()) {
+ c.withEnv("ENABLE_API_BASED_MODULES", "'true'");
c.withEnv("ENABLE_MODULES", String.join(",", enableModules));
}
- if (defaultVectorizerModule != null) {
- c.withEnv("DEFAULT_VECTORIZER_MODULE", defaultVectorizerModule);
- }
- if (contextionaryUrl != null) {
- c.withEnv("CONTEXTIONARY_URL", contextionaryUrl);
- }
if (!telemetry) {
c.withEnv("DISABLE_TELEMETRY", "true");
}
+ environment.forEach((name, value) -> c.withEnv(name, value));
c.withCreateContainerCmdModifier(cmd -> cmd.withHostName("weaviate"));
return c;
}
diff --git a/src/it/java/io/weaviate/integration/CollectionsITest.java b/src/it/java/io/weaviate/integration/CollectionsITest.java
index fc70e0fde..59083c44b 100644
--- a/src/it/java/io/weaviate/integration/CollectionsITest.java
+++ b/src/it/java/io/weaviate/integration/CollectionsITest.java
@@ -60,7 +60,6 @@ public void testCrossReferences() throws IOException {
// Assert: Things --ownedBy-> Owners
Assertions.assertThat(things.config.get())
- // Assertions.assertThat(client.collections.getConfig(nsOwners))
.as("after create Things").get()
.satisfies(c -> {
Assertions.assertThat(c.references())
diff --git a/src/it/java/io/weaviate/integration/DataITest.java b/src/it/java/io/weaviate/integration/DataITest.java
index 50fc5205d..aed87e17c 100644
--- a/src/it/java/io/weaviate/integration/DataITest.java
+++ b/src/it/java/io/weaviate/integration/DataITest.java
@@ -15,6 +15,7 @@
import io.weaviate.client6.v1.collections.VectorIndex.IndexingStrategy;
import io.weaviate.client6.v1.collections.Vectorizer;
import io.weaviate.client6.v1.collections.object.Vectors;
+import io.weaviate.client6.v1.collections.object.WeaviateObject;
import io.weaviate.containers.Container;
public class DataITest extends ConcurrentTest {
@@ -62,6 +63,29 @@ public void testCreateGetDelete() throws IOException {
Assertions.assertThat(object).isEmpty().as("object not exists after deletion");
}
+ @Test
+ public void testBlobData() throws IOException {
+ var nsCats = ns("Cats");
+
+ client.collections.create(nsCats,
+ collection -> collection.properties(
+ Property.text("breed"),
+ Property.blob("img")));
+
+ var cats = client.collections.use(nsCats);
+ var ragdollPng = EncodedMedia.IMAGE;
+ var ragdoll = cats.data.insert(Map.of(
+ "breed", "ragdoll",
+ "img", ragdollPng));
+
+ var got = cats.data.get(ragdoll.metadata().id(),
+ cat -> cat.returnProperties("img"));
+
+ Assertions.assertThat(got).get()
+ .extracting(WeaviateObject::properties, InstanceOfAssertFactories.MAP)
+ .extractingByKey("img").isEqualTo(ragdollPng);
+ }
+
private static void createTestCollections() throws IOException {
var awardsGrammy = unique("Grammy");
client.collections.create(awardsGrammy);
diff --git a/src/it/java/io/weaviate/integration/EncodedMedia.java b/src/it/java/io/weaviate/integration/EncodedMedia.java
new file mode 100644
index 000000000..d075de08f
--- /dev/null
+++ b/src/it/java/io/weaviate/integration/EncodedMedia.java
@@ -0,0 +1,6 @@
+package io.weaviate.integration;
+
+class EncodedMedia {
+ public static final String IMAGE = "/9j/4AAQSkZJRgABAQAAkACQAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAACQAAAAAQAAAJAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAnKgAwAEAAAAAQAAAbsAAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/AABEIAbsCcgMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2wBDABwcHBwcHDAcHDBEMDAwRFxEREREXHRcXFxcXHSMdHR0dHR0jIyMjIyMjIyoqKioqKjExMTExNzc3Nzc3Nzc3Nz/2wBDASIkJDg0OGA0NGDmnICc5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ub/3QAEACj/2gAMAwEAAhEDEQA/AOkooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/9DpKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/R6SiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/0ukooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/9PpKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/U6SiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/1ekooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/9bpKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/X6SiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoophdR3pN23AfRUfmj0pRIDU+0j3HYfRRRViCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooJA5NABRURlXOBzR5hPas3Viuo7EtFM3+tPBzVKSewgoooqgCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//Q6SiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKQkDk0ALTWdV61C0pPC1HWMqvYdhzOzewpAKMU6uaUmyhRS4BoBFPAqUmwGqxBwelTVXPWplORXRRn9liaHUUUV0khRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAASAMmqruWNSSN2qsa5a9S3uoqKJBUgquCRT9xrl5irE+aX6VEGp4NaRmKw8N60+o6OR0rojV7isSUU0MDTq3TT2JCiiimAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH/9HpKKKKACiiigAooooAKKKKACiiigAooooAKKKKACimNIq1XZ2br0rOVRIdiZpQOF5qAkscmiiueU29x2ClxRS1k2MKQmjNFZtjFXrVioV61N2roo7EsgPWpE61F3qRfvCsoP3kNk1FFFekQFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUhOBmlpr/doYFZzUZqRutRmvMqfEzRCU4U2nCsxjqXOKSigCQN608GoaASKpTsKxP1oBI61GG9akzW8agrDwQaWo8elKG7GumNTuTYfRR1orUQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/9LpKKKKACiiigAooooAKKKKACiiigAoozjk1A8vZfzqZSS3AlZ1XrVdpGb2FM+tFc8qjZVgpaSlrFsYtFJmiochi5pKSlrNsYUtJSimgJFqQ9KjWnt0rqhsQyv3qVeoqIdalXqKwj8SGyeiiivTICiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKa/3adTX+7SewFZutRmnt1phrzanxMtCU6m06oGLS0lFIYtFFFAC0oJFNooAlDZp1Q0oYirjMViXp0p4b1qMHNL1rohUtsS0S0VGCRTwQa6YzTFYWiiirEFFFFABRRRQAUUUUAFFFFABRRRQB//T6SiiigAooooAKKKKACiiigAoJwMmioJmx8tTKXKrgMdyx9qjpM0VxuV9ShaWkorNyGOpM0lFQ2MWiiipGFFFFAC0opKUVSESLTm+7TVpz9K6V8JJXHWpF+8KiHWpV+8KwhuhlmiiivTICiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKa/3adTX+6aT2AqN1plPbrTK82puy0FLSUtQMWlpKKAFooopDFopKKAFooooAWnBvWm0UJtATA0vuKhBxU1dEJXJY8HNLUIJDVNXXTnzIlhRRRWggooooAKKKKACiiigAooooA//U6SiiigAooooAKKKKACiiigAqlKcuau1Qb7xrnxD0SGhtFJS1xModRSUtIBaKSloGFLSUUALRRRQAtKKSlqkIkWlfpSLSv0rdfCIrjrUi/eFRCpV+8KxhuhlqiiivTICiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKa/3TTqY/3TSewFRutMpzdabXmz3ZYUtJS1IC0tJS0hhRRRQAtFJS0ALRSUtAC0tJS07AFSKcio6cnWrhuDFbrUw6VC/WpV6V00n7zRLHUUUV0khRRRQAUUUUAFFFFABRRRQB//1ekooooAKKKKACiiigAooooAKzj1P1rRrNPU1zYjoNBS02lrkKHUUUUgFpaSikMWiiigApaSimAtOptLVIRItK/SmrTn+7Wy+ERXHWpV+8KiFSL94VlDdAW6KKK9IkKKKKACiiigAooooAKKKaXUUXAdRURlHYU3zT7VPOhXJ6Kr+aaPNNLnQXRYoqES04SKafMguSUUgYHoaWqGFFFFABRRRQAUUUUAFMk+4afTJPuGk9gKZplOam1509ygp1NpagY6ikpaAClpKKQxaKSloAWlptOpgLRRRTAWnL1plOXrVLcBz9alT7tQv1qZPu10UviZL2HUUUV1EhRRRQAUUUUAFFFFABRRRQB//9bpKKKKACiiigAooooAKKKKACs09TWlWaeprmxHQaEpaSlFcjGLS0UUhi0UUUAFLSUUALRSUUAOpabSiqQEi0r9KatK/StVsIg71Kv3hUPepV++KzhuhFyiiivSEFFFFABRRUTSgcCk2luBISB1qIy+lQFyTSYJrJ1OxPN2HF80mSaUAU6s7hbuN2ml2inUUgshNoo2ilophoJtFJt9KfRQFkR/MKcshFOpCAaabQvQlWQHrUlUypHSlWQitFU7j5u5bopiyA0+tE77FBRRRTAKZJ9w0+mSfcNJ7AUT1ptOPWm9686W7GLS02nVIxaKSlpDFopKKAFooooAWlpKKBjqWkpaYgpy9abTl61S3AV+tTJ92oX61Mn3a6KXxMT2HUUUV1EhRRRQAUUUUAFFFFABRRRQB//X6SiiigAooooAKKKKACiiigArNPU1pVmnqfrXNiOg0JSikpRXIxjqKKKQxaKKSgBaKSigBaKSigBaWkopiJVpX6VGDT2PFaJ6AVz1qVfvioj1qRP9YKUNyS9RRTGdU616DdgH1G0ir7mqzzFuOgqIZaspVexLkStKWpvLdaUKBTqy1e4t9xAAKdRRVWC4tFJmjNOwrjqKZupN1AXJKKi3ijfQLmJaKj30bqAuSUtR7qXdQO4+mlQaM0tFguQnKmpUlI4NLUTJ3FTqtg22LgYN0p1Z2StTpPjhua1jV7lKRapkn3DTlYMMimyfcNaPYooHrTe9OPWm96857sBaWm06pGhaKSloGFLSUUhi0tJRQAtLSUUAOpabTqaAWnL1ptKvWqW4Dn61Kn3ahfrUyfdropfEJj6KKK6iQooooAKKKKACiiigAooooA//0OkooooAKKKKACiiigAooooAKzT1P1rSrMPU/WubEdBoSnCm04VysY6iiipGFFFFABRRRQIKKKSgBaKSimA8U5ulMWkZwoqkK4w9adGwDg9hUBJbk8CkU54qoaMzlKxde47JVfJagAU8YrVtvchtsRVqUU3NGapIE0h9GaiL0wuaLicyYtTS9Q5NJRclyJS9N3GmUUrk3HZNJmkopCuLmjNNooC47NGabRmgLj9xpdxqOjNMdyYPTw9V80ZouNSLgYGlzVQMRUoequWpEpUGoihFPDUuQaTRW5CGZTxUxn3JtbrTWUGoCMUrtC5mhSRmk71EfvEUoYjrWLRalclpaYCDTqgtC0tNpaQxaWm0tAxaWm0tAC0tJRSGOpabS0AOpy9abTl61aAV+tTR/dqF+tTR/dropfEJj6KKK6iQooooAKKKKACiiigAooooA//R6SiiigAooooAKKKKACiiigArMPU1p1mHqa5sR0GhKcKbThXKxi0tJRSAWikopALSUUUwCikozQIKCQOTUbSdl5NRn1c5p2E2Sby3C/nShMc9TTVOTU+OKtbE7lZqanSnNTE6VUDGoSAkUu41HS1oZXH5NGTTaKYXFopKWkAUUUlAC0UmaaWAoAdmjNRFx2pNzHtRYCXNGag3N3IpNx9RTsBYzRmoNx9KcHFFgJc0ZpgNLmkIfmjNNzRmgLj6XNMzS5oGPDEU4OajopjuT76YxzTKWgfMQ/8ALSpKj/jqSsZlwGYxyKcH7GlppGai/c1uS5par5ZakVwaLFJklLTaKRQ6lptLSGOpabS0ALS0lLSAdTl60wU4dapAPfrU0f3agbrU8f3a6aXxCY+iiiuoQUUUUAFFFFABRRRQAUUUUAf/0ukooooAKKKKACiiigAooooAKzD1NadZbdT9a5q/QaEp4pgp4rlYxaKKKQBRSUUCCjNMZwtREs3XgU0hNkhkGcLzTGJPU49qTIHC0lMhsM44HFFFFAh6datH7tVk61Yb7tXEpFRu9Rr0qR+hqJTxVQMKg+nUynCtDEdRSUUwuLRTc00sB1oC4/NMMgHHU1EWZunApMqtFhkhYn2qMso96jLE0lOwDy57cU3JPWkop2ELRSUtABS5NJRRYBwNPDn61FR0pWHcsBgelOzVYH8DUgfsaVgt2Js0ZpmaWkIfmnZqOlBoC5LQaaDQaBkf8VSVF/FUprKZrTAUtNp1ZmolNK0+koAbuZfenhwaSmFc0x3J6KgDMvWpAwNJopMkzS5ptFIq5JS1HmnA0hj6eOtR04U0BI3Wp4/u1XNWI/u100fiEx9FFFdQgooooAKKKKACiiigAooooA//0+kooooAKKKKACiiigAooooAKxUYng9a2qxSpzleornr9BNjwalFQBgalBrlZSY+kpCwFRGQnhKSQmyQsB1qIuzfd4HrTcd25NBOadrEthwOnJo60UUyRKWiikAUUUUwJE61Yb7tVl61aP3apFIpP0NRL0qV+9Qr0q6exz1R9Opopa1MLi5pM0xnC9ahLF/YUWGkStJ2Xmo/dqbuA4FMJJ607FEhc9qZSUU7ALRRRTsAtFJRRYBaKSiiwC0UlFFgFopKKLALS57Gm0UWAeCR06VIrg1BR70mgLWaXNVxJjg1KDmpsS0Sg049KiBp+eKQXGfxVLUP8VTdqyqG1MKWm0tZGwtFFFABRRRQAlMK45FPoouA0ORw1Sgg1GRmm4I+7T0Y0yxSg1CH7NxT8ilYtMmFOFRhhjmm+YW4T86SQ7k4bLEDtVuP7tUkXaMVdj+7XTR3AfRRRXUIKKKKACiiigAooooAKKKKAP/U6SiiigAooooAKKKKACiiigArKkG2Rh71q1n3aYcOO9Y1o3iJlchW69aTYezUmaWuO5Nxuwdzml9hxRRTuAlFFFIQUUUUwCiiigAooooAcvWrR+7VQdanz8tNMaK79DUK9Kmboar7go5rWmc9UkzULydlqNnLewqPPpWyiZqI/POTyaQsTTaKqxdhaWm0tOwC0tJRRYBaKSiiwhaKSigBaKSigBaKSkzQA6lpuaM0WAWikzS5osFgopKKLBYWkDFaKKLATq4apQapcjkVKkvZqhxJcexMT81Tdqr5ywqftWFQ0pC0UlFZG46ikooAWikpaACiiikAUUUlABSYX3FLSUwFCL3OasxhegqsBV2JQo96aV3qUhrthtoq7HwgqiPmkyK0QMDFdNJFBRRRW4BRRRQAUUUUAFFFFABRRRQB/9XpKKKKACiiigAooooAKKKKACmOgdStPooaAx3UqcUytOaIMNwrOZCprinCzIaG0tNorMQtFFFABRRRQAUUUUAFJRRQAoqXPy1XLAU4fN1ppBciduDVEnJq5JwpqjXTRWhmx1FNzS1vYkWlptLRYB1FJRRYQ6im0UWAdRSUoFFgsFOCmngU8D0FA7EeyjZU+1vSk2t6UFcpBtppFTn3FMNArENJmnGo6LCsPzRmmZpc0WCw+im5pc07CFoopaLDsJSGn4prUrBYapINX1YEVnd6vL0rnrIqJLRUe4jrTwc1z2LFpaSikMWlptLQAtFJRQAtFJRQAtFAGalAC8mgY+NMfM1PZi3yr0pnzP8ASrkUW3k1tCFykLDHtGT1qaiiupK2gwooopgFFFFABRRRQAUUUUAFFFFAH//W6SiiigAooooAKKKKACiiigAooooAKhkiDcipqKTV9wMp4iDUJGK2WRW61Sltz1H51zzpW2JaKVFKQQeabzWDRItFJmjNIBaKbuppaiwrjyQKjLE9KSlqrCuJipk9Kjp68Uxoim6Gs+tCXoazc8100NmSx1FNpa6LCH0UlFFhC0tNoosA6lFAFOAzSCwAVOkZapYYCxxWvFbqgy3JpMuMClFalucVdW1QDnmrNFI1UUiMRRjtQYoz2qSigZWe1iboMVSlsmHK81rUUCcUzl3QioCMV081uko9D61iT27RHDCmjKULFCjNOZSKZVWJHZpc0zNGaLCsSg04Gos04GiwE1RtTs0xqVhsZ3q8vSqA61fHSuesNDqTGOlKKK5hgG9afTKTBHSiwElLTAfWnZpWGLS02lFIYtOA9aBgU4AtTSGKPapFQk1LHCW9quKgQYFbwpjSI44gnJ61NRRXQlbYoKKKKYBRRRQAUUUUAFFFFABRRRQAUUUUAf/X6SiiigAooooAKKKKACiiigAooooAKKKKACiiigCCSBZORwazZInjOCK2aRlDDDDNZyppiaMHJpMmtCW07pz7VRZSvWueULENDKSnUlSSFLSUtIBacKbSimhkclZlaj1mPwxFdOH6iEpabRXVYQ+lzTKWiwh1PUUiip1QtQOwiqTwK0Le1ZjnHFTW1oCNz8VpgBRgVDZoojUjWMYWn0UVJYUUUUAFFFFABRRRQAU10V12sMinUUAYtzZFPmXlaynQiuvrPuLJX+aPg+lUmQ4nOEU2rMkZRiCMVCV7irM7Dc04Go6XNFgsTg0jGowaUmiwDR1rRFZ6csK0K5a4C0tFFcwxaKSlpAFGKUU6mMAD3p2ewFAUseauRQZ68VShcaRCkbMelXo4QvLVKqqowKdXRGmkWkFFFFaDCiiigAooooAKKKKACiiigAooooAKKKKACiiigD//0OkooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACopIUk68H1qWik1cDIlt3j7cVWIroCM8Gqc1qG+ZOD6VjKl2IcTKoqRo2U4IphFYNEBSim0A0APYZFZs6kPn1rSBzUM0e8e9aU58srgZtFOKMO1JXemAoGakVaavJwBk1qW9q74yMUNgkV4oWc9K2YLVYxl+T6VPFCkQ46+tTVm3c0SCiiikUFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAV57aOdeeD61hTW7wthxXS0x0SRdjjIpp2E1c5NkzyKiKkVr3Nm8Pzp8y/yrOODxWikjNogoNPKntSBCTihyRJJCuWz6VcpiJsXFSVw1JXYC0tJS1iMKUClAqVUzTSHYYBmpkiLHirEduTyauKoUYFbRplqJDHAF5arFFFbpJbFBRRRTAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//R6SiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBjxq45qhJasORyPatKiplBMTRhGMimYrdaNH+8Kha1Q9DisXSfQlxMjFO5rR+yD1oFoPWp9mxcplsgbtTfs241tC1QdTmpljRPuitIwkh8pnQWWME8CtJVCDaKdRWqRSVgooopjCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKz7ixR8tHwfTtWhRSaBo5trd1OGFATb2romRX+8M1A1qh6HFZyjLuQ4GNg0uK1DZ+/6Ugs/esvZsXKZwU08Ia0har3NTLDGvQVSpMfKUI4GbtV5IVXrzUtFaxgkUkFFFFWMKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP//S6SiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/2Q==";
+
+}
diff --git a/src/it/java/io/weaviate/integration/NearVectorQueryITest.java b/src/it/java/io/weaviate/integration/NearVectorQueryITest.java
deleted file mode 100644
index 863652781..000000000
--- a/src/it/java/io/weaviate/integration/NearVectorQueryITest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package io.weaviate.integration;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.assertj.core.api.Assertions;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import io.weaviate.ConcurrentTest;
-import io.weaviate.client6.WeaviateClient;
-import io.weaviate.client6.v1.collections.Property;
-import io.weaviate.client6.v1.collections.VectorIndex;
-import io.weaviate.client6.v1.collections.VectorIndex.IndexingStrategy;
-import io.weaviate.client6.v1.collections.Vectorizer;
-import io.weaviate.client6.v1.collections.object.Vectors;
-import io.weaviate.client6.v1.collections.query.GroupedQueryResult;
-import io.weaviate.client6.v1.collections.query.MetadataField;
-import io.weaviate.client6.v1.collections.query.NearVector;
-import io.weaviate.containers.Container;
-
-public class NearVectorQueryITest extends ConcurrentTest {
- private static final WeaviateClient client = Container.WEAVIATE.getClient();
-
- private static final String COLLECTION = unique("Things");
- private static final String VECTOR_INDEX = "bring_your_own";
- private static final List CATEGORIES = List.of("red", "green");
-
- /**
- * One of the inserted vectors which will be used as target vector for search.
- */
- private static Float[] searchVector;
-
- @BeforeClass
- public static void beforeAll() throws IOException {
- createTestCollection();
- var created = populateTest(10);
- searchVector = created.values().iterator().next();
- }
-
- @Test
- public void testNearVector() {
- // TODO: test that we return the results in the expected order
- // Because re-ranking should work correctly
- var things = client.collections.use(COLLECTION);
- var result = things.query.nearVector(searchVector,
- opt -> opt
- .distance(2f)
- .limit(3)
- .returnMetadata(MetadataField.DISTANCE));
-
- Assertions.assertThat(result.objects).hasSize(3);
- float maxDistance = Collections.max(result.objects,
- Comparator.comparing(obj -> obj.metadata.distance())).metadata.distance();
- Assertions.assertThat(maxDistance).isLessThanOrEqualTo(2f);
- }
-
- @Test
- public void testNearVector_groupBy() {
- // TODO: test that we return the results in the expected order
- // Because re-ranking should work correctly
- var things = client.collections.use(COLLECTION);
- var result = things.query.nearVector(searchVector,
- new NearVector.GroupBy("category", 2, 5),
- opt -> opt.distance(10f));
-
- Assertions.assertThat(result.groups)
- .as("group per category").containsOnlyKeys(CATEGORIES)
- .hasSizeLessThanOrEqualTo(2)
- .allSatisfy((category, group) -> {
- Assertions.assertThat(group)
- .as("group name").returns(category, GroupedQueryResult.Group::name);
- Assertions.assertThat(group.numberOfObjects())
- .as("[%s] has 1+ object", category).isLessThanOrEqualTo(5L);
- });
-
- Assertions.assertThat(result.objects)
- .as("object belongs a group")
- .allMatch(obj -> result.groups.get(obj.belongsToGroup).objects().contains(obj));
-
- }
-
- /**
- * Insert 10 objects with random vectors.
- *
- * @returns IDs of inserted objects and their corresponding vectors.
- */
- private static Map populateTest(int n) throws IOException {
- var created = new HashMap();
-
- var things = client.collections.use(COLLECTION);
- for (int i = 0; i < n; i++) {
- var vector = randomVector(10, -.01f, .001f);
- var object = things.data.insert(
- Map.of("category", CATEGORIES.get(i % CATEGORIES.size())),
- metadata -> metadata
- .id(randomUUID())
- .vectors(Vectors.of(VECTOR_INDEX, vector)));
-
- created.put(object.metadata().id(), vector);
- }
-
- return created;
- }
-
- /**
- * Create {@link COLLECTION} with {@link VECTOR_INDEX} vector index.
- *
- * @throws IOException
- */
- private static void createTestCollection() throws IOException {
- client.collections.create(COLLECTION, cfg -> cfg
- .properties(Property.text("category"))
- .vector(VECTOR_INDEX, new VectorIndex<>(IndexingStrategy.hnsw(), Vectorizer.none())));
- }
-}
diff --git a/src/it/java/io/weaviate/integration/SearchITest.java b/src/it/java/io/weaviate/integration/SearchITest.java
new file mode 100644
index 000000000..38b83c26a
--- /dev/null
+++ b/src/it/java/io/weaviate/integration/SearchITest.java
@@ -0,0 +1,225 @@
+package io.weaviate.integration;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.assertj.core.api.Assertions;
+import org.assertj.core.api.InstanceOfAssertFactories;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+
+import io.weaviate.ConcurrentTest;
+import io.weaviate.client6.WeaviateClient;
+import io.weaviate.client6.v1.collections.Property;
+import io.weaviate.client6.v1.collections.Reference;
+import io.weaviate.client6.v1.collections.VectorIndex;
+import io.weaviate.client6.v1.collections.VectorIndex.IndexingStrategy;
+import io.weaviate.client6.v1.collections.Vectorizer;
+import io.weaviate.client6.v1.collections.object.Vectors;
+import io.weaviate.client6.v1.collections.query.GroupedQueryResult;
+import io.weaviate.client6.v1.collections.query.MetadataField;
+import io.weaviate.client6.v1.collections.query.NearText;
+import io.weaviate.client6.v1.collections.query.NearVector;
+import io.weaviate.containers.Container;
+import io.weaviate.containers.Container.ContainerGroup;
+import io.weaviate.containers.Contextionary;
+import io.weaviate.containers.Img2VecNeural;
+import io.weaviate.containers.Weaviate;
+
+public class SearchITest extends ConcurrentTest {
+ private static final ContainerGroup compose = Container.compose(
+ Weaviate.custom()
+ .withContextionaryUrl(Contextionary.URL)
+ .withImageInference(Img2VecNeural.URL, Img2VecNeural.MODULE)
+ .build(),
+ Container.IMG2VEC_NEURAL,
+ Container.CONTEXTIONARY);
+ @ClassRule // Bind containers to the lifetime of the test
+ public static final TestRule _rule = compose.asTestRule();
+ private static final WeaviateClient client = compose.getClient();
+
+ private static final String COLLECTION = unique("Things");
+ private static final String VECTOR_INDEX = "bring_your_own";
+ private static final List CATEGORIES = List.of("red", "green");
+
+ /**
+ * One of the inserted vectors which will be used as target vector for search.
+ */
+ private static Float[] searchVector;
+
+ @BeforeClass
+ public static void beforeAll() throws IOException {
+ createTestCollection();
+ var created = populateTest(10);
+ searchVector = created.values().iterator().next();
+ }
+
+ @Test
+ public void testNearVector() {
+ var things = client.collections.use(COLLECTION);
+ var result = things.query.nearVector(searchVector,
+ opt -> opt
+ .distance(2f)
+ .limit(3)
+ .returnMetadata(MetadataField.DISTANCE));
+
+ Assertions.assertThat(result.objects).hasSize(3);
+ float maxDistance = Collections.max(result.objects,
+ Comparator.comparing(obj -> obj.metadata.distance())).metadata.distance();
+ Assertions.assertThat(maxDistance).isLessThanOrEqualTo(2f);
+ }
+
+ @Test
+ public void testNearVector_groupBy() {
+ var things = client.collections.use(COLLECTION);
+ var result = things.query.nearVector(searchVector,
+ new NearVector.GroupBy("category", 2, 5),
+ opt -> opt.distance(10f));
+
+ Assertions.assertThat(result.groups)
+ .as("group per category").containsOnlyKeys(CATEGORIES)
+ .hasSizeLessThanOrEqualTo(2)
+ .allSatisfy((category, group) -> {
+ Assertions.assertThat(group)
+ .as("group name").returns(category, GroupedQueryResult.Group::name);
+ Assertions.assertThat(group.numberOfObjects())
+ .as("[%s] has 1+ object", category).isLessThanOrEqualTo(5L);
+ });
+
+ Assertions.assertThat(result.objects)
+ .as("object belongs a group")
+ .allMatch(obj -> result.groups.get(obj.belongsToGroup).objects().contains(obj));
+ }
+
+ /**
+ * Insert 10 objects with random vectors.
+ *
+ * @returns IDs of inserted objects and their corresponding vectors.
+ */
+ private static Map populateTest(int n) throws IOException {
+ var created = new HashMap();
+
+ var things = client.collections.use(COLLECTION);
+ for (int i = 0; i < n; i++) {
+ var vector = randomVector(10, -.01f, .001f);
+ var object = things.data.insert(
+ Map.of("category", CATEGORIES.get(i % CATEGORIES.size())),
+ metadata -> metadata
+ .id(randomUUID())
+ .vectors(Vectors.of(VECTOR_INDEX, vector)));
+
+ created.put(object.metadata().id(), vector);
+ }
+
+ return created;
+ }
+
+ /**
+ * Create {@link COLLECTION} with {@link VECTOR_INDEX} vector index.
+ *
+ * @throws IOException
+ */
+ private static void createTestCollection() throws IOException {
+ client.collections.create(COLLECTION, cfg -> cfg
+ .properties(Property.text("category"))
+ .vector(VECTOR_INDEX, new VectorIndex<>(IndexingStrategy.hnsw(), Vectorizer.none())));
+ }
+
+ @Test
+ public void testNearText() throws IOException {
+ var nsSongs = ns("Songs");
+ client.collections.create(nsSongs,
+ col -> col
+ .properties(Property.text("title"))
+ .vector(new VectorIndex<>(IndexingStrategy.hnsw(), Vectorizer.text2vecContextionary())));
+
+ var songs = client.collections.use(nsSongs);
+ var submarine = songs.data.insert(Map.of("title", "Yellow Submarine"));
+ songs.data.insert(Map.of("title", "Run Through The Jungle"));
+ songs.data.insert(Map.of("title", "Welcome To The Jungle"));
+
+ var result = songs.query.nearText("forest",
+ opt -> opt
+ .distance(0.5f)
+ .moveTo(.98f, to -> to.concepts("tropical"))
+ .moveAway(.4f, away -> away.uuids(submarine.metadata().id()))
+ .returnProperties("title"));
+
+ Assertions.assertThat(result.objects).hasSize(2)
+ .extracting(obj -> obj.properties).allSatisfy(
+ properties -> Assertions.assertThat(properties)
+ .allSatisfy((_k, v) -> Assertions.assertThat((String) v).contains("Jungle")));
+ }
+
+ @Test
+ public void testNearText_groupBy() throws IOException {
+ var vectorIndex = new VectorIndex<>(IndexingStrategy.hnsw(), Vectorizer.text2vecContextionary());
+
+ var nsArtists = ns("Artists");
+ client.collections.create(nsArtists,
+ col -> col
+ .properties(Property.text("name"))
+ .vector(vectorIndex));
+
+ var artists = client.collections.use(nsArtists);
+ var beatles = artists.data.insert(Map.of("name", "Beatles"));
+ var ccr = artists.data.insert(Map.of("name", "CCR"));
+
+ var nsSongs = ns("Songs");
+ client.collections.create(nsSongs,
+ col -> col
+ .properties(Property.text("title"))
+ .references(Property.reference("performedBy", nsArtists))
+ .vector(vectorIndex));
+
+ var songs = client.collections.use(nsSongs);
+ songs.data.insert(Map.of("title", "Yellow Submarine"),
+ s -> s.reference("performedBy", Reference.objects(beatles)));
+ songs.data.insert(Map.of("title", "Run Through The Jungle"),
+ s -> s.reference("performedBy", Reference.objects(ccr)));
+
+ var result = songs.query.nearText("nature",
+ new NearText.GroupBy("performedBy", 2, 1),
+ opt -> opt
+ .returnProperties("title"));
+
+ Assertions.assertThat(result.groups).hasSize(2)
+ .containsOnlyKeys(
+ "weaviate://localhost/%s/%s".formatted(nsArtists, beatles.metadata().id()),
+ "weaviate://localhost/%s/%s".formatted(nsArtists, ccr.metadata().id()));
+ }
+
+ @Test
+ // @Ignore("no fitting image to test with")
+ public void testNearImage() throws IOException {
+ var nsCats = ns("Cats");
+
+ client.collections.create(nsCats,
+ collection -> collection
+ .properties(
+ Property.text("breed"),
+ Property.blob("img"))
+ .vector(new VectorIndex<>(
+ IndexingStrategy.hnsw(),
+ Vectorizer.img2VecNeuralVectorizer(
+ i2v -> i2v.imageFields("img")))));
+
+ var cats = client.collections.use(nsCats);
+ cats.data.insert(Map.of(
+ "breed", "ragdoll",
+ "img", EncodedMedia.IMAGE));
+
+ var got = cats.query.nearImage(EncodedMedia.IMAGE,
+ opt -> opt.returnProperties("breed"));
+
+ Assertions.assertThat(got.objects).hasSize(1).first()
+ .extracting(obj -> obj.properties, InstanceOfAssertFactories.MAP)
+ .extractingByKey("breed").isEqualTo("ragdoll");
+ }
+}
diff --git a/src/main/java/io/weaviate/client6/internal/codec/grpc/v1/SearchMarshaler.java b/src/main/java/io/weaviate/client6/internal/codec/grpc/v1/SearchMarshaler.java
index ca6769f01..9e30ef515 100644
--- a/src/main/java/io/weaviate/client6/internal/codec/grpc/v1/SearchMarshaler.java
+++ b/src/main/java/io/weaviate/client6/internal/codec/grpc/v1/SearchMarshaler.java
@@ -3,6 +3,7 @@
import org.apache.commons.lang3.StringUtils;
import io.weaviate.client6.grpc.protocol.v1.WeaviateProtoBaseSearch;
+import io.weaviate.client6.grpc.protocol.v1.WeaviateProtoBaseSearch.NearTextSearch;
import io.weaviate.client6.grpc.protocol.v1.WeaviateProtoSearchGet;
import io.weaviate.client6.grpc.protocol.v1.WeaviateProtoSearchGet.MetadataRequest;
import io.weaviate.client6.grpc.protocol.v1.WeaviateProtoSearchGet.PropertiesRequest;
@@ -10,6 +11,8 @@
import io.weaviate.client6.internal.GRPC;
import io.weaviate.client6.internal.codec.grpc.GrpcMarshaler;
import io.weaviate.client6.v1.collections.query.CommonQueryOptions;
+import io.weaviate.client6.v1.collections.query.NearImage;
+import io.weaviate.client6.v1.collections.query.NearText;
import io.weaviate.client6.v1.collections.query.NearVector;
public class SearchMarshaler implements GrpcMarshaler {
@@ -31,6 +34,15 @@ public SearchMarshaler addGroupBy(NearVector.GroupBy gb) {
return this;
}
+ public SearchMarshaler addGroupBy(NearText.GroupBy gb) {
+ var groupBy = WeaviateProtoSearchGet.GroupBy.newBuilder();
+ groupBy.addPath(gb.property());
+ groupBy.setNumberOfGroups(gb.maxGroups());
+ groupBy.setObjectsPerGroup(gb.maxObjectsPerGroup());
+ req.setGroupBy(groupBy);
+ return this;
+ }
+
public SearchMarshaler addNearVector(NearVector nv) {
setCommon(nv.common());
@@ -43,10 +55,56 @@ public SearchMarshaler addNearVector(NearVector nv) {
nearVector.setDistance(nv.distance());
}
+ // TODO: add targets, vector_for_targets
req.setNearVector(nearVector);
return this;
}
+ public SearchMarshaler addNearImage(NearImage ni) {
+ setCommon(ni.common());
+
+ var nearImage = WeaviateProtoBaseSearch.NearImageSearch.newBuilder();
+ nearImage.setImage(ni.image());
+
+ if (ni.certainty() != null) {
+ nearImage.setCertainty(ni.certainty());
+ } else if (ni.distance() != null) {
+ nearImage.setDistance(ni.distance());
+ }
+
+ req.setNearImage(nearImage);
+ return this;
+ }
+
+ public SearchMarshaler addNearText(NearText nt) {
+ setCommon(nt.common());
+
+ var nearText = WeaviateProtoBaseSearch.NearTextSearch.newBuilder();
+ nearText.addAllQuery(nt.text());
+
+ if (nt.certainty() != null) {
+ nearText.setCertainty(nt.certainty());
+ } else if (nt.distance() != null) {
+ nearText.setDistance(nt.distance());
+ }
+
+ // TODO: add targets
+ if (nt.moveTo() != null) {
+ var to = NearTextSearch.Move.newBuilder();
+ nt.moveTo().appendTo(to);
+ nearText.setMoveTo(to);
+ }
+
+ if (nt.moveAway() != null) {
+ var away = NearTextSearch.Move.newBuilder();
+ nt.moveAway().appendTo(away);
+ nearText.setMoveAway(away);
+ }
+
+ req.setNearText(nearText);
+ return this;
+ }
+
private void setCommon(CommonQueryOptions o) {
if (o.limit() != null) {
req.setLimit(o.limit());
diff --git a/src/main/java/io/weaviate/client6/v1/collections/AtomicDataType.java b/src/main/java/io/weaviate/client6/v1/collections/AtomicDataType.java
index da54b1c28..38c33ed22 100644
--- a/src/main/java/io/weaviate/client6/v1/collections/AtomicDataType.java
+++ b/src/main/java/io/weaviate/client6/v1/collections/AtomicDataType.java
@@ -6,10 +6,13 @@ public enum AtomicDataType {
@SerializedName("text")
TEXT,
@SerializedName("int")
- INT;
+ INT,
+ @SerializedName("blob")
+ BLOB;
public static boolean isAtomic(String type) {
return type.equals(TEXT.name().toLowerCase())
- || type.equals(INT.name().toLowerCase());
+ || type.equals(INT.name().toLowerCase())
+ || type.equals(BLOB.name().toLowerCase());
}
}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/Collection.java b/src/main/java/io/weaviate/client6/v1/collections/Collection.java
index 81298a029..870701311 100644
--- a/src/main/java/io/weaviate/client6/v1/collections/Collection.java
+++ b/src/main/java/io/weaviate/client6/v1/collections/Collection.java
@@ -9,48 +9,47 @@
public record Collection(String name, List properties, List references, Vectors vectors) {
- public static Collection with(String name, Consumer options) {
- var config = new Configuration(options);
+ public static Collection with(String name, Consumer options) {
+ var config = new Builder(options);
return new Collection(name, config.properties, config.references, config.vectors);
}
- // Tucked Builder for additional collection configuration.
- public static class Configuration {
- public List properties = new ArrayList<>();
+ public static class Builder {
+ private List properties = new ArrayList<>();
public List references = new ArrayList<>();
- public Vectors vectors;
+ private Vectors vectors;
- public Configuration properties(Property... properties) {
+ public Builder properties(Property... properties) {
this.properties = Arrays.asList(properties);
return this;
}
- public Configuration references(ReferenceProperty... references) {
+ public Builder references(ReferenceProperty... references) {
this.references = Arrays.asList(references);
return this;
}
- public Configuration vectors(Vectors vectors) {
+ public Builder vectors(Vectors vectors) {
this.vectors = vectors;
return this;
}
- public Configuration vector(VectorIndex vector) {
+ public Builder vector(VectorIndex vector) {
this.vectors = Vectors.of(vector);
return this;
}
- public Configuration vector(String name, VectorIndex vector) {
+ public Builder vector(String name, VectorIndex vector) {
this.vectors = new Vectors(name, vector);
return this;
}
- public Configuration vectors(Consumer named) {
+ public Builder vectors(Consumer named) {
this.vectors = Vectors.with(named);
return this;
}
- Configuration(Consumer options) {
+ Builder(Consumer options) {
options.accept(this);
}
}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/CollectionsClient.java b/src/main/java/io/weaviate/client6/v1/collections/CollectionsClient.java
index fa3ff38de..48f41c4df 100644
--- a/src/main/java/io/weaviate/client6/v1/collections/CollectionsClient.java
+++ b/src/main/java/io/weaviate/client6/v1/collections/CollectionsClient.java
@@ -73,6 +73,7 @@ private static class VectorizerSerde
@Override
public Vectorizer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
+ // TODO: deserialize different kinds of vectorizers
return Vectorizer.none();
}
@@ -116,7 +117,7 @@ public void create(String name) throws IOException {
});
}
- public void create(String name, Consumer options) throws IOException {
+ public void create(String name, Consumer options) throws IOException {
var collection = Collection.with(name, options);
ClassicHttpRequest httpPost = ClassicRequestBuilder
.post(config.baseUrl() + "/schema")
diff --git a/src/main/java/io/weaviate/client6/v1/collections/ContextionaryVectorizer.java b/src/main/java/io/weaviate/client6/v1/collections/ContextionaryVectorizer.java
new file mode 100644
index 000000000..1bb580ada
--- /dev/null
+++ b/src/main/java/io/weaviate/client6/v1/collections/ContextionaryVectorizer.java
@@ -0,0 +1,37 @@
+package io.weaviate.client6.v1.collections;
+
+import java.util.Map;
+import java.util.function.Consumer;
+
+import com.google.gson.annotations.SerializedName;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public class ContextionaryVectorizer extends Vectorizer {
+ @SerializedName("text2vec-contextionary")
+ private Map configuration;
+
+ public static ContextionaryVectorizer of() {
+ return new Builder().build();
+ }
+
+ public static ContextionaryVectorizer of(Consumer fn) {
+ var builder = new Builder();
+ fn.accept(builder);
+ return builder.build();
+ }
+
+ public static class Builder {
+ private boolean vectorizeCollectionName = false;
+
+ public Builder vectorizeCollectionName() {
+ this.vectorizeCollectionName = true;
+ return this;
+ }
+
+ public ContextionaryVectorizer build() {
+ return new ContextionaryVectorizer(Map.of("vectorizeClassName", vectorizeCollectionName));
+ }
+ }
+}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/HNSW.java b/src/main/java/io/weaviate/client6/v1/collections/HNSW.java
index cac6b45b4..938c44ffa 100644
--- a/src/main/java/io/weaviate/client6/v1/collections/HNSW.java
+++ b/src/main/java/io/weaviate/client6/v1/collections/HNSW.java
@@ -17,26 +17,26 @@ public enum Distance {
this(null, null);
}
- static HNSW with(Consumer options) {
- var opt = new Options(options);
+ static HNSW with(Consumer options) {
+ var opt = new Builder(options);
return new HNSW(opt.distance, opt.skip);
}
- public static class Options {
- public Distance distance;
- public Boolean skip;
+ public static class Builder {
+ private Distance distance;
+ private Boolean skip;
- public Options distance(Distance distance) {
+ public Builder distance(Distance distance) {
this.distance = distance;
return this;
}
- public Options disableIndexation() {
+ public Builder disableIndexation() {
this.skip = true;
return this;
}
- public Options(Consumer options) {
+ public Builder(Consumer options) {
options.accept(this);
}
}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/Img2VecNeuralVectorizer.java b/src/main/java/io/weaviate/client6/v1/collections/Img2VecNeuralVectorizer.java
new file mode 100644
index 000000000..a0efc5c61
--- /dev/null
+++ b/src/main/java/io/weaviate/client6/v1/collections/Img2VecNeuralVectorizer.java
@@ -0,0 +1,40 @@
+package io.weaviate.client6.v1.collections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import com.google.gson.annotations.SerializedName;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public class Img2VecNeuralVectorizer extends Vectorizer {
+ @SerializedName("img2vec-neural")
+ private Map configuration;
+
+ public static Img2VecNeuralVectorizer of() {
+ return new Builder().build();
+ }
+
+ public static Img2VecNeuralVectorizer of(Consumer fn) {
+ var builder = new Builder();
+ fn.accept(builder);
+ return builder.build();
+ }
+
+ public static class Builder {
+ private List imageFields = new ArrayList<>();
+
+ public Builder imageFields(String... fields) {
+ this.imageFields = Arrays.asList(fields);
+ return this;
+ }
+
+ public Img2VecNeuralVectorizer build() {
+ return new Img2VecNeuralVectorizer(Map.of("imageFields", imageFields));
+ }
+ }
+}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/Multi2VecClipVectorizer.java b/src/main/java/io/weaviate/client6/v1/collections/Multi2VecClipVectorizer.java
new file mode 100644
index 000000000..305e8373a
--- /dev/null
+++ b/src/main/java/io/weaviate/client6/v1/collections/Multi2VecClipVectorizer.java
@@ -0,0 +1,100 @@
+package io.weaviate.client6.v1.collections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import com.google.gson.annotations.SerializedName;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public class Multi2VecClipVectorizer extends Vectorizer {
+ @SerializedName("multi2vec-clip")
+ private Map configuration;
+
+ public static Multi2VecClipVectorizer of() {
+ return new Builder().build();
+ }
+
+ public static Multi2VecClipVectorizer of(Consumer fn) {
+ var builder = new Builder();
+ fn.accept(builder);
+ return builder.build();
+ }
+
+ public static class Builder {
+ private boolean vectorizeCollectionName = false;
+ private String inferenceUrl;
+ private Map imageFields = new HashMap<>();
+ private Map textFields = new HashMap<>();
+
+ public Builder inferenceUrl(String inferenceUrl) {
+ this.inferenceUrl = inferenceUrl;
+ return this;
+ }
+
+ public Builder imageFields(String... fields) {
+ Arrays.stream(fields).forEach(f -> imageFields.put(f, null));
+ return this;
+ }
+
+ public Builder imageField(String field, float weight) {
+ imageFields.put(field, weight);
+ return this;
+ }
+
+ public Builder textFields(String... fields) {
+ Arrays.stream(fields).forEach(f -> textFields.put(f, null));
+ return this;
+ }
+
+ public Builder textField(String field, float weight) {
+ textFields.put(field, weight);
+ return this;
+ }
+
+ public Builder vectorizeCollectionName() {
+ this.vectorizeCollectionName = true;
+ return this;
+ }
+
+ public Multi2VecClipVectorizer build() {
+ return new Multi2VecClipVectorizer(new HashMap<>() {
+ {
+ put("vectorizeClassName", vectorizeCollectionName);
+ if (inferenceUrl != null) {
+ put("inferenceUrl", inferenceUrl);
+ }
+
+ var _imageFields = new ArrayList();
+ var _imageWeights = new ArrayList();
+ splitEntries(imageFields, _imageFields, _imageWeights);
+
+ var _textFields = new ArrayList();
+ var _textWeights = new ArrayList();
+ splitEntries(imageFields, _textFields, _textWeights);
+
+ put("imageFields", _imageFields);
+ put("textFields", _textFields);
+ put("weights", Map.of(
+ "imageWeights", _imageWeights,
+ "textWeights", _textWeights));
+ }
+ });
+ }
+
+ private void splitEntries(Map map, List keys, List values) {
+ map.entrySet().forEach(entry -> {
+ keys.add(entry.getKey());
+ var value = entry.getValue();
+ if (value != null) {
+ values.add(value);
+ }
+ });
+ }
+ }
+}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/Property.java b/src/main/java/io/weaviate/client6/v1/collections/Property.java
index 9c2456eac..bb9293abb 100644
--- a/src/main/java/io/weaviate/client6/v1/collections/Property.java
+++ b/src/main/java/io/weaviate/client6/v1/collections/Property.java
@@ -19,6 +19,11 @@ public static Property integer(String name) {
return new Property(name, AtomicDataType.INT);
}
+ /** Add blob property with default configuration. */
+ public static Property blob(String name) {
+ return new Property(name, AtomicDataType.BLOB);
+ }
+
public static ReferenceProperty reference(String name, String... collections) {
return new ReferenceProperty(name, Arrays.asList(collections));
}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/Text2VecWeaviateVectorizer.java b/src/main/java/io/weaviate/client6/v1/collections/Text2VecWeaviateVectorizer.java
new file mode 100644
index 000000000..db1f9a0f3
--- /dev/null
+++ b/src/main/java/io/weaviate/client6/v1/collections/Text2VecWeaviateVectorizer.java
@@ -0,0 +1,72 @@
+package io.weaviate.client6.v1.collections;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import com.google.gson.annotations.SerializedName;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public class Text2VecWeaviateVectorizer extends Vectorizer {
+ @SerializedName("text2vec-weaviate")
+ private Map configuration;
+
+ public static Text2VecWeaviateVectorizer of() {
+ return new Builder().build();
+ }
+
+ public static Text2VecWeaviateVectorizer of(Consumer fn) {
+ var builder = new Builder();
+ fn.accept(builder);
+ return builder.build();
+ }
+
+ public static final String SNOWFLAKE_ARCTIC_EMBED_L_20 = "Snowflake/snowflake-arctic-embed-l-v2.0";
+ public static final String SNOWFLAKE_ARCTIC_EMBED_M_15 = "Snowflake/snowflake-arctic-embed-m-v1.5";
+
+ public static class Builder {
+ private boolean vectorizeCollectionName = false;
+ private String baseUrl;
+ private Integer dimensions;
+ private String model;
+
+ public Builder baseUrl(String baseUrl) {
+ this.baseUrl = baseUrl;
+ return this;
+ }
+
+ public Builder dimensions(int dimensions) {
+ this.dimensions = dimensions;
+ return this;
+ }
+
+ public Builder model(String model) {
+ this.model = model;
+ return this;
+ }
+
+ public Builder vectorizeCollectionName() {
+ this.vectorizeCollectionName = true;
+ return this;
+ }
+
+ public Text2VecWeaviateVectorizer build() {
+ return new Text2VecWeaviateVectorizer(new HashMap<>() {
+ {
+ put("vectorizeClassName", vectorizeCollectionName);
+ if (baseUrl != null) {
+ put("baseURL", baseUrl);
+ }
+ if (dimensions != null) {
+ put("dimensions", dimensions);
+ }
+ if (model != null) {
+ put("model", model);
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/VectorIndex.java b/src/main/java/io/weaviate/client6/v1/collections/VectorIndex.java
index 5db348263..b8aea7f0c 100644
--- a/src/main/java/io/weaviate/client6/v1/collections/VectorIndex.java
+++ b/src/main/java/io/weaviate/client6/v1/collections/VectorIndex.java
@@ -29,7 +29,7 @@ public static IndexingStrategy hnsw() {
return new HNSW();
}
- public static IndexingStrategy hnsw(Consumer options) {
+ public static IndexingStrategy hnsw(Consumer options) {
return HNSW.with(options);
}
}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/Vectorizer.java b/src/main/java/io/weaviate/client6/v1/collections/Vectorizer.java
index ad9c4260f..f2e07be5a 100644
--- a/src/main/java/io/weaviate/client6/v1/collections/Vectorizer.java
+++ b/src/main/java/io/weaviate/client6/v1/collections/Vectorizer.java
@@ -1,8 +1,44 @@
package io.weaviate.client6.v1.collections;
+import java.util.function.Consumer;
+
// This class is WIP, I haven't decided how to structure it yet.
public abstract class Vectorizer {
public static NoneVectorizer none() {
return new NoneVectorizer();
}
+
+ public static ContextionaryVectorizer text2vecContextionary() {
+ return ContextionaryVectorizer.of();
+ }
+
+ public static ContextionaryVectorizer text2vecContextionary(Consumer fn) {
+ return ContextionaryVectorizer.of(fn);
+ }
+
+ // TODO: add test cases
+ public static Text2VecWeaviateVectorizer text2vecWeaviate() {
+ return Text2VecWeaviateVectorizer.of();
+ }
+
+ public static Text2VecWeaviateVectorizer text2vecWeaviate(Consumer fn) {
+ return Text2VecWeaviateVectorizer.of(fn);
+ }
+
+ // TODO: add test cases
+ public static Multi2VecClipVectorizer multi2vecClip() {
+ return Multi2VecClipVectorizer.of();
+ }
+
+ public static Multi2VecClipVectorizer multi2vecClip(Consumer fn) {
+ return Multi2VecClipVectorizer.of(fn);
+ }
+
+ public static Img2VecNeuralVectorizer img2VecNeuralVectorizer() {
+ return Img2VecNeuralVectorizer.of();
+ }
+
+ public static Img2VecNeuralVectorizer img2VecNeuralVectorizer(Consumer fn) {
+ return Img2VecNeuralVectorizer.of(fn);
+ }
}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/aggregate/TopOccurrences.java b/src/main/java/io/weaviate/client6/v1/collections/aggregate/TopOccurrences.java
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/main/java/io/weaviate/client6/v1/collections/data/DataClient.java b/src/main/java/io/weaviate/client6/v1/collections/data/DataClient.java
index e8878e1e8..e6030f4cd 100644
--- a/src/main/java/io/weaviate/client6/v1/collections/data/DataClient.java
+++ b/src/main/java/io/weaviate/client6/v1/collections/data/DataClient.java
@@ -207,7 +207,11 @@ private static Object convertProtoValue(Value value) {
return value.getIntValue();
} else if (value.hasNumberValue()) {
return value.getNumberValue();
- } else if (value.hasDateValue()) {
+ } else if (value.hasBlobValue()) {
+ return value.getBlobValue();
+ } else if (value.hasDateValue())
+
+ {
OffsetDateTime offsetDateTime = OffsetDateTime.parse(value.getDateValue());
return Date.from(offsetDateTime.toInstant());
} else {
diff --git a/src/main/java/io/weaviate/client6/v1/collections/object/ObjectMetadata.java b/src/main/java/io/weaviate/client6/v1/collections/object/ObjectMetadata.java
index e4cf36602..61ffcb9de 100644
--- a/src/main/java/io/weaviate/client6/v1/collections/object/ObjectMetadata.java
+++ b/src/main/java/io/weaviate/client6/v1/collections/object/ObjectMetadata.java
@@ -10,8 +10,8 @@ public static ObjectMetadata with(Consumer options) {
}
public static class Builder {
- public String id;
- public Vectors vectors;
+ private String id;
+ private Vectors vectors;
public Builder id(String id) {
this.id = id;
diff --git a/src/main/java/io/weaviate/client6/v1/collections/query/NearImage.java b/src/main/java/io/weaviate/client6/v1/collections/query/NearImage.java
new file mode 100644
index 000000000..d6b978cc6
--- /dev/null
+++ b/src/main/java/io/weaviate/client6/v1/collections/query/NearImage.java
@@ -0,0 +1,30 @@
+package io.weaviate.client6.v1.collections.query;
+
+import java.util.function.Consumer;
+
+public record NearImage(String image, Float distance, Float certainty, CommonQueryOptions common) {
+
+ public static NearImage with(String image, Consumer fn) {
+ var opt = new Builder();
+ fn.accept(opt);
+ return new NearImage(image, opt.distance, opt.certainty, new CommonQueryOptions(opt));
+ }
+
+ public static class Builder extends CommonQueryOptions.Builder {
+ private Float distance;
+ private Float certainty;
+
+ public Builder distance(float distance) {
+ this.distance = distance;
+ return this;
+ }
+
+ public Builder certainty(float certainty) {
+ this.certainty = certainty;
+ return this;
+ }
+ }
+
+ public static record GroupBy(String property, int maxGroups, int maxObjectsPerGroup) {
+ }
+}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/query/NearText.java b/src/main/java/io/weaviate/client6/v1/collections/query/NearText.java
new file mode 100644
index 000000000..6185b772b
--- /dev/null
+++ b/src/main/java/io/weaviate/client6/v1/collections/query/NearText.java
@@ -0,0 +1,87 @@
+package io.weaviate.client6.v1.collections.query;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+
+import io.weaviate.client6.grpc.protocol.v1.WeaviateProtoBaseSearch;
+
+public record NearText(List text, Float distance, Float certainty, Move moveTo, Move moveAway,
+ CommonQueryOptions common) {
+
+ public static NearText with(String text, Consumer fn) {
+ return with(List.of(text), fn);
+ }
+
+ public static NearText with(List text, Consumer fn) {
+ var opt = new Builder();
+ fn.accept(opt);
+ return new NearText(text, opt.distance, opt.certainty, opt.moveTo, opt.moveAway, new CommonQueryOptions(opt));
+ }
+
+ public static class Builder extends CommonQueryOptions.Builder {
+ private Float distance;
+ private Float certainty;
+ private Move moveTo;
+ private Move moveAway;
+
+ public Builder distance(float distance) {
+ this.distance = distance;
+ return this;
+ }
+
+ public Builder certainty(float certainty) {
+ this.certainty = certainty;
+ return this;
+ }
+
+ public Builder moveTo(float force, Consumer fn) {
+ var move = new Move(force);
+ fn.accept(move);
+ this.moveTo = move;
+ return this;
+ }
+
+ public Builder moveAway(float force, Consumer fn) {
+ var move = new Move(force);
+ fn.accept(move);
+ this.moveAway = move;
+ return this;
+ }
+
+ }
+
+ public static class Move {
+ private final Float force;
+ private List objects = new ArrayList<>();
+ private List concepts = new ArrayList<>();
+
+ Move(float force) {
+ this.force = force;
+ }
+
+ public Move uuids(String... uuids) {
+ this.objects = Arrays.asList(uuids);
+ return this;
+ }
+
+ public Move concepts(String... concepts) {
+ this.concepts = Arrays.asList(concepts);
+ return this;
+ }
+
+ public void appendTo(WeaviateProtoBaseSearch.NearTextSearch.Move.Builder move) {
+ move.setForce(force);
+ if (!objects.isEmpty()) {
+ move.addAllUuids(objects);
+ }
+ if (!concepts.isEmpty()) {
+ move.addAllConcepts(concepts);
+ }
+ }
+ }
+
+ public static record GroupBy(String property, int maxGroups, int maxObjectsPerGroup) {
+ }
+}
diff --git a/src/main/java/io/weaviate/client6/v1/collections/query/QueryClient.java b/src/main/java/io/weaviate/client6/v1/collections/query/QueryClient.java
index 66a8a6540..f701d5b2b 100644
--- a/src/main/java/io/weaviate/client6/v1/collections/query/QueryClient.java
+++ b/src/main/java/io/weaviate/client6/v1/collections/query/QueryClient.java
@@ -31,6 +31,13 @@ public QueryClient(String collectionName, GrpcClient grpc) {
this.collectionName = collectionName;
}
+ public QueryResult nearVector(Float[] vector) {
+ var query = NearVector.with(vector, opt -> {
+ });
+ var req = new SearchMarshaler(collectionName).addNearVector(query);
+ return search(req.marshal());
+ }
+
public QueryResult nearVector(Float[] vector, Consumer options) {
var query = NearVector.with(vector, options);
var req = new SearchMarshaler(collectionName).addNearVector(query);
@@ -53,6 +60,33 @@ public GroupedQueryResult nearVector(Float[] vector, NearVector.GroupBy group
return searchGrouped(req.marshal());
}
+ public QueryResult nearText(String text, Consumer fn) {
+ var query = NearText.with(text, fn);
+ var req = new SearchMarshaler(collectionName).addNearText(query);
+ return search(req.marshal());
+ }
+
+ public GroupedQueryResult nearText(String text, NearText.GroupBy groupBy, Consumer fn) {
+ var query = NearText.with(text, fn);
+ var req = new SearchMarshaler(collectionName)
+ .addNearText(query)
+ .addGroupBy(groupBy);
+ return searchGrouped(req.marshal());
+ }
+
+ public QueryResult nearText(String text) {
+ var query = NearText.with(text, opt -> {
+ });
+ var req = new SearchMarshaler(collectionName).addNearText(query);
+ return search(req.marshal());
+ }
+
+ public QueryResult nearImage(String image, Consumer fn) {
+ var query = NearImage.with(image, fn);
+ var req = new SearchMarshaler(collectionName).addNearImage(query);
+ return search(req.marshal());
+ }
+
private QueryResult search(SearchRequest req) {
var reply = grpcClient.grpc.search(req);
return deserializeUntyped(reply);