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
5 changes: 2 additions & 3 deletions src/it/java/io/weaviate/integration/AggregationITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@
import io.weaviate.ConcurrentTest;
import io.weaviate.client6.v1.api.WeaviateClient;
import io.weaviate.client6.v1.api.collections.Property;
import io.weaviate.client6.v1.api.collections.Vectorizers;
import io.weaviate.client6.v1.api.collections.Vectors;
import io.weaviate.client6.v1.api.collections.aggregate.AggregateResponseGroup;
import io.weaviate.client6.v1.api.collections.aggregate.AggregateResponseGrouped;
import io.weaviate.client6.v1.api.collections.aggregate.Aggregation;
import io.weaviate.client6.v1.api.collections.aggregate.GroupBy;
import io.weaviate.client6.v1.api.collections.aggregate.GroupedBy;
import io.weaviate.client6.v1.api.collections.aggregate.IntegerAggregation;
import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw;
import io.weaviate.client6.v1.api.collections.vectorizers.NoneVectorizer;
import io.weaviate.containers.Container;

public class AggregationITest extends ConcurrentTest {
Expand All @@ -36,7 +35,7 @@ public static void beforeAll() throws IOException {
.properties(
Property.text("category"),
Property.integer("price"))
.vector(Hnsw.of(new NoneVectorizer())));
.vectors(Vectorizers.none()));

var things = client.collections.use(COLLECTION);
for (var category : List.of("Shoes", "Hat", "Jacket")) {
Expand Down
11 changes: 6 additions & 5 deletions src/it/java/io/weaviate/integration/CollectionsITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
import io.weaviate.client6.v1.api.collections.InvertedIndex;
import io.weaviate.client6.v1.api.collections.Property;
import io.weaviate.client6.v1.api.collections.Replication;
import io.weaviate.client6.v1.api.collections.VectorIndex;
import io.weaviate.client6.v1.api.collections.Vectorizer;
import io.weaviate.client6.v1.api.collections.Vectorizers;
import io.weaviate.client6.v1.api.collections.config.Shard;
import io.weaviate.client6.v1.api.collections.config.ShardStatus;
import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw;
Expand All @@ -28,18 +29,18 @@ public void testCreateGetDelete() throws IOException {
client.collections.create(collectionName,
col -> col
.properties(Property.text("username"), Property.integer("age"))
.vector(Hnsw.of(new NoneVectorizer())));
.vectors(Vectorizers.none()));

var thingsCollection = client.collections.getConfig(collectionName);

Assertions.assertThat(thingsCollection).get()
.hasFieldOrPropertyWithValue("collectionName", collectionName)
.extracting(CollectionConfig::vectors, InstanceOfAssertFactories.map(String.class, VectorIndex.class))
.extracting(CollectionConfig::vectors, InstanceOfAssertFactories.map(String.class, Vectorizer.class))
.as("default vector").extractingByKey("default")
.satisfies(defaultVector -> {
Assertions.assertThat(defaultVector).extracting(VectorIndex::vectorizer)
Assertions.assertThat(defaultVector)
.as("has none vectorizer").isInstanceOf(NoneVectorizer.class);
Assertions.assertThat(defaultVector).extracting(VectorIndex::config)
Assertions.assertThat(defaultVector).extracting(Vectorizer::vectorIndex)
.isInstanceOf(Hnsw.class);
});

Expand Down
7 changes: 3 additions & 4 deletions src/it/java/io/weaviate/integration/DataITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.weaviate.ConcurrentTest;
import io.weaviate.client6.v1.api.WeaviateClient;
import io.weaviate.client6.v1.api.collections.Property;
import io.weaviate.client6.v1.api.collections.Vectorizers;
import io.weaviate.client6.v1.api.collections.Vectors;
import io.weaviate.client6.v1.api.collections.WeaviateObject;
import io.weaviate.client6.v1.api.collections.data.BatchReference;
Expand All @@ -20,8 +21,6 @@
import io.weaviate.client6.v1.api.collections.query.QueryMetadata;
import io.weaviate.client6.v1.api.collections.query.QueryReference;
import io.weaviate.client6.v1.api.collections.query.Where;
import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw;
import io.weaviate.client6.v1.api.collections.vectorizers.NoneVectorizer;
import io.weaviate.containers.Container;

public class DataITest extends ConcurrentTest {
Expand Down Expand Up @@ -107,7 +106,7 @@ private static void createTestCollections() throws IOException {
Property.integer("age"))
.references(
Property.reference("hasAwards", awardsGrammy, awardsOscar))
.vectors(named -> named.vector(VECTOR_INDEX, Hnsw.of(new NoneVectorizer()))));
.vectors(Vectorizers.none(VECTOR_INDEX)));
}

@Test
Expand Down Expand Up @@ -223,7 +222,7 @@ public void testUpdate() throws IOException {
collection -> collection
.properties(Property.text("title"), Property.integer("year"))
.references(Property.reference("writtenBy", nsAuthors))
.vector(Hnsw.of(new NoneVectorizer())));
.vectors(Vectorizers.none()));

var authors = client.collections.use(nsAuthors);
var walter = authors.data.insert(Map.of("name", "walter scott"));
Expand Down
24 changes: 10 additions & 14 deletions src/it/java/io/weaviate/integration/SearchITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.weaviate.ConcurrentTest;
import io.weaviate.client6.v1.api.WeaviateClient;
import io.weaviate.client6.v1.api.collections.Property;
import io.weaviate.client6.v1.api.collections.Vectorizers;
import io.weaviate.client6.v1.api.collections.Vectors;
import io.weaviate.client6.v1.api.collections.WeaviateMetadata;
import io.weaviate.client6.v1.api.collections.WeaviateObject;
Expand All @@ -27,10 +28,6 @@
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.Where;
import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw;
import io.weaviate.client6.v1.api.collections.vectorizers.Img2VecNeuralVectorizer;
import io.weaviate.client6.v1.api.collections.vectorizers.NoneVectorizer;
import io.weaviate.client6.v1.api.collections.vectorizers.Text2VecContextionaryVectorizer;
import io.weaviate.containers.Container;
import io.weaviate.containers.Container.ContainerGroup;
import io.weaviate.containers.Contextionary;
Expand Down Expand Up @@ -133,7 +130,7 @@ private static Map<String, Float[]> populateTest(int n) throws IOException {
private static void createTestCollection() throws IOException {
client.collections.create(COLLECTION, cfg -> cfg
.properties(Property.text("category"))
.vector(VECTOR_INDEX, Hnsw.of(new NoneVectorizer())));
.vectors(Vectorizers.none(VECTOR_INDEX)));
}

@Test
Expand All @@ -142,7 +139,7 @@ public void testNearText() throws IOException {
client.collections.create(nsSongs,
col -> col
.properties(Property.text("title"))
.vector(Hnsw.of(Text2VecContextionaryVectorizer.of())));
.vectors(Vectorizers.text2vecContextionary()));

var songs = client.collections.use(nsSongs);
var submarine = songs.data.insert(Map.of("title", "Yellow Submarine"));
Expand All @@ -164,13 +161,13 @@ public void testNearText() throws IOException {

@Test
public void testNearText_groupBy() throws IOException {
var vectorIndex = Hnsw.of(Text2VecContextionaryVectorizer.of());
var vectorizer = Vectorizers.text2vecContextionary();

var nsArtists = ns("Artists");
client.collections.create(nsArtists,
col -> col
.properties(Property.text("name"))
.vector(vectorIndex));
.vectors(vectorizer));

var artists = client.collections.use(nsArtists);
var beatles = artists.data.insert(Map.of("name", "Beatles"));
Expand All @@ -181,7 +178,7 @@ public void testNearText_groupBy() throws IOException {
col -> col
.properties(Property.text("title"))
.references(Property.reference("performedBy", nsArtists))
.vector(vectorIndex));
.vectors(vectorizer));

var songs = client.collections.use(nsSongs);
songs.data.insert(Map.of("title", "Yellow Submarine"),
Expand All @@ -208,9 +205,8 @@ public void testNearImage() throws IOException {
.properties(
Property.text("breed"),
Property.blob("img"))
.vector(Hnsw.of(
Img2VecNeuralVectorizer.of(
i2v -> i2v.imageFields("img")))));
.vectors(Vectorizers.img2vecNeural(
i2v -> i2v.imageFields("img"))));

var cats = client.collections.use(nsCats);
cats.data.insert(Map.of(
Expand Down Expand Up @@ -325,7 +321,7 @@ public void testNearObject() throws IOException {
client.collections.create(nsAnimals,
collection -> collection
.properties(Property.text("kind"))
.vector(Hnsw.of(Text2VecContextionaryVectorizer.of())));
.vectors(Vectorizers.text2vecContextionary()));

var animals = client.collections.use(nsAnimals);

Expand Down Expand Up @@ -354,7 +350,7 @@ public void testHybrid() throws IOException {
client.collections.create(nsHobbies,
collection -> collection
.properties(Property.text("name"), Property.text("description"))
.vector(Hnsw.of(Text2VecContextionaryVectorizer.of())));
.vectors(Vectorizers.text2vecContextionary()));

var hobbies = client.collections.use(nsHobbies);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public record CollectionConfig(
@SerializedName("description") String description,
@SerializedName("properties") List<Property> properties,
List<ReferenceProperty> references,
@SerializedName("vectorConfig") Map<String, VectorIndex> vectors,
@SerializedName("vectorConfig") Map<String, Vectorizer> vectors,
@SerializedName("multiTenancyConfig") MultiTenancy multiTenancy,
@SerializedName("shardingConfig") Sharding sharding,
@SerializedName("replicationConfig") Replication replication,
Expand Down Expand Up @@ -88,7 +88,7 @@ public static class Builder implements ObjectBuilder<CollectionConfig> {
private String description;
private Map<String, Property> properties = new HashMap<>();
private Map<String, ReferenceProperty> references = new HashMap<>();
private Map<String, VectorIndex> vectors = new HashMap<>();
private Map<String, Vectorizer> vectors = new HashMap<>();
private MultiTenancy multiTenancy;
private Sharding sharding;
private Replication replication;
Expand Down Expand Up @@ -131,23 +131,14 @@ private List<ReferenceProperty> referenceList() {
return this.references.values().stream().toList();
}

public Builder vector(VectorIndex vector) {
this.vectors.put(VectorIndex.DEFAULT_VECTOR_NAME, vector);
return this;
}

public Builder vector(String name, VectorIndex vector) {
this.vectors.put(name, vector);
return this;
}

public Builder vectors(Map<String, VectorIndex> vectors) {
public final Builder vectors(Map<String, Vectorizer> vectors) {
this.vectors.putAll(vectors);
return this;
}

public Builder vectors(Function<VectorsBuilder, ObjectBuilder<Map<String, VectorIndex>>> fn) {
this.vectors = fn.apply(new VectorsBuilder()).build();
@SafeVarargs
public final Builder vectors(Map.Entry<String, Vectorizer>... vectors) {
this.vectors.putAll(Map.ofEntries(vectors));
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

public interface VectorIndex {
static final String DEFAULT_VECTOR_NAME = "default";
static final VectorIndex DEFAULT_VECTOR_INDEX = Hnsw.of();

public enum Kind implements JsonEnum<Kind> {
HNSW("hnsw"),
Expand Down Expand Up @@ -48,8 +49,6 @@ default String type() {
return _kind().jsonValue();
}

Vectorizer vectorizer();

Object config();

public static enum CustomTypeAdapterFactory implements TypeAdapterFactory {
Expand Down Expand Up @@ -79,7 +78,6 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
init(gson);
}

final var vectorizerAdapter = gson.getDelegateAdapter(this, TypeToken.get(Vectorizer.class));
final var writeAdapter = gson.getDelegateAdapter(this, TypeToken.get(rawType));
return (TypeAdapter<T>) new TypeAdapter<VectorIndex>() {

Expand All @@ -89,13 +87,11 @@ public void write(JsonWriter out, VectorIndex value) throws IOException {
out.name("vectorIndexType");
out.value(value._kind().jsonValue());

var config = writeAdapter.toJsonTree((T) value.config());
config.getAsJsonObject().remove("vectorizer");
out.name("vectorIndexConfig");
var config = writeAdapter.toJsonTree((T) value.config());
config.getAsJsonObject().remove("name");
Streams.write(config, out);

out.name("vectorizer");
vectorizerAdapter.write(out, value.vectorizer());
out.endObject();
}

Expand All @@ -117,7 +113,6 @@ public VectorIndex read(JsonReader in) throws IOException {
}

var config = jsonObject.get("vectorIndexConfig").getAsJsonObject();
config.add("vectorizer", jsonObject.get("vectorizer"));
return adapter.fromJsonTree(config);
}
}.nullSafe();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@
import java.io.IOException;
import java.util.EnumMap;
import java.util.Map;
import java.util.function.Function;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.Streams;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import io.weaviate.client6.v1.api.collections.vectorizers.Img2VecNeuralVectorizer;
import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecClipVectorizer;
import io.weaviate.client6.v1.api.collections.vectorizers.NoneVectorizer;
import io.weaviate.client6.v1.api.collections.vectorizers.Text2VecContextionaryVectorizer;
import io.weaviate.client6.v1.api.collections.vectorizers.Text2VecWeaviateVectorizer;
import io.weaviate.client6.v1.internal.ObjectBuilder;
import io.weaviate.client6.v1.internal.json.JsonEnum;

public interface Vectorizer {
Expand Down Expand Up @@ -48,6 +52,8 @@ public static Kind valueOfJson(String jsonValue) {

Object _self();

VectorIndex vectorIndex();

public static enum CustomTypeAdapterFactory implements TypeAdapterFactory {
INSTANCE;

Expand Down Expand Up @@ -84,28 +90,48 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
public void write(JsonWriter out, Vectorizer value) throws IOException {
TypeAdapter<T> adapter = (TypeAdapter<T>) delegateAdapters.get(value._kind());

out.beginObject();
out.name(value._kind().jsonValue());
adapter.write(out, (T) value._self());
out.endObject();
// Serialize vectorizer config as { "vectorizer-kind": { ... } }
// and remove "vectorIndex" object which every vectorizer has.
var vectorizer = new JsonObject();
var config = adapter.toJsonTree((T) value._self());

// This will create { "vectorIndexType": "", "vectorIndexConfig": { ... } }
// to which we just need to add "vectorizer": { ... } key.
var vectorIndex = config.getAsJsonObject().remove("vectorIndex");

vectorizer.add(value._kind().jsonValue(), config);
vectorIndex.getAsJsonObject().add("vectorizer", vectorizer);

Streams.write(vectorIndex, out);
}

@Override
public Vectorizer read(JsonReader in) throws IOException {
in.beginObject();
var vectorizerName = in.nextName();
var jsonObject = JsonParser.parseReader(in).getAsJsonObject();

// VectorIndex.CustomTypeAdapterFactory expects keys
// ["vectorIndexType", "vectorIndexConfig"].
var vectorIndex = new JsonObject();
vectorIndex.add("vectorIndexType", jsonObject.get("vectorIndexType"));
vectorIndex.add("vectorIndexConfig", jsonObject.get("vectorIndexConfig"));

var vectorizerObject = jsonObject.get("vectorizer").getAsJsonObject();
var vectorizerName = vectorizerObject.keySet().iterator().next();

Vectorizer.Kind kind;
try {
var kind = Vectorizer.Kind.valueOfJson(vectorizerName);
var adapter = delegateAdapters.get(kind);
return adapter.read(in);
kind = Vectorizer.Kind.valueOfJson(vectorizerName);
} catch (IllegalArgumentException e) {
return null;
} finally {
if (in.peek() == JsonToken.BEGIN_OBJECT) {
in.beginObject();
}
in.endObject();
}

var adapter = delegateAdapters.get(kind);
var concreteVectorizer = vectorizerObject.get(vectorizerName).getAsJsonObject();

// Each individual vectorizer has a `VectorIndex vectorIndex` field.
concreteVectorizer.add("vectorIndex", vectorIndex);

return adapter.fromJsonTree(concreteVectorizer);
}
}.nullSafe();
}
Expand Down
Loading