Skip to content
Draft
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
4 changes: 2 additions & 2 deletions src/collections/collection/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface Collection<T = undefined, N = string, V = undefined> {
/** This namespace includes all the backup methods available to you when backing up a collection in Weaviate. */
backup: BackupCollection;
/** This namespace includes all the CRUD methods available to you when modifying the configuration of the collection in Weaviate. */
config: Config<T>;
config: Config<T, V>;
/** This namespace includes all the CUD methods available to you when modifying the data of the collection in Weaviate. */
data: Data<T>;
/** This namespace includes the methods by which you can create the `FilterValue<V>` values for use when filtering queries over your collection. */
Expand Down Expand Up @@ -139,7 +139,7 @@ const collection = <T, N, V>(
return {
aggregate: aggregateCollection,
backup: backupCollection(connection, capitalizedName),
config: config<T>(connection, capitalizedName, dbVersionSupport, tenant),
config: config<T, V>(connection, capitalizedName, dbVersionSupport, tenant),
data: data<T>(connection, capitalizedName, dbVersionSupport, consistencyLevel, tenant),
filter: filter<T extends undefined ? any : T>(),
generate: generate<T, V>(connection, capitalizedName, dbVersionSupport, consistencyLevel, tenant),
Expand Down
19 changes: 16 additions & 3 deletions src/collections/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ import {
} from './types/index.js';
import { classToCollection, makeVectorsConfig, resolveProperty, resolveReference } from './utils.js';

const config = <T>(
const config = <T, V>(
connection: Connection,
name: string,
dbVersionSupport: DbVersionSupport,
tenant?: string
): Config<T> => {
): Config<T, V> => {
const getRaw = new ClassGetter(connection).withClassName(name).do;
return {
addProperty: (property: PropertyConfigCreate<any>) =>
Expand Down Expand Up @@ -96,12 +96,14 @@ const config = <T>(
},
dropInvertedIndex: (propertyName, indexName) =>
connection.delete(`/schema/${name}/properties/${propertyName}/index/${indexName}`, null),
dropVectorIndex: (vectorName) =>
connection.delete(`/schema/${name}/vectors/${vectorName ? String(vectorName) : 'default'}/index`, null),
};
};

export default config;

export interface Config<T> {
export interface Config<T, V> {
/**
* Add a property to the collection in Weaviate.
*
Expand Down Expand Up @@ -173,6 +175,17 @@ export interface Config<T> {
* @returns {Promise<void>} A promise that resolves when the index has been dropped.
*/
dropInvertedIndex: (propertyName: string, indexName: InvertedIndexName) => Promise<void>;
/**
* Drop the vector index associated with a named vector of this collection.
*
* This is a destructive operation. The index will need to be regenerated if you wish to use it again.
*
* @param {keyof V & string} [vectorName] The name of the vector to drop the index from. If not provided, the default vector index will be dropped.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param {keyof V & string} [vectorName] The name of the vector to drop the index from. If not provided, the default vector index will be dropped.
* @param {keyof V & string} [vectorName] The name of the vector to drop the index from. If not provided, the "default" vector index will be dropped.

Maybe a nit, but I think it's good to be specific about the fact that Weaviate doesn't have the notion of a default vector index, and it's the client that will fallback to "default" input. E.g. if the user's only index is called "my-only-index" they should expect to see an error on dropVectorIndex(undefined).

I would argue this parameter should be required tho, similarly to how when you're trying to delete a GH repo you need to manually enter the repo's name to confirm. Not insisting on it tho, just my first response to vectorName?.

* @returns {Promise<void>} A promise that resolves when the index has been dropped.
*/
dropVectorIndex: <VN extends V extends undefined ? string : keyof V & string>(
vectorName?: VN
) => Promise<void>;
}

export class VectorIndex {
Expand Down
2 changes: 1 addition & 1 deletion src/collections/config/types/vectorIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export type VectorDistance = 'cosine' | 'dot' | 'l2-squared' | 'hamming';
export type PQEncoderType = 'kmeans' | 'tile';
export type PQEncoderDistribution = 'log-normal' | 'normal';

export type VectorIndexType = 'hnsw' | 'hfresh' | 'flat' | 'dynamic' | string;
export type VectorIndexType = 'hnsw' | 'hfresh' | 'flat' | 'dynamic' | 'none' | string;

export type VectorIndexFilterStrategy = 'sweeping' | 'acorn';

Expand Down
70 changes: 70 additions & 0 deletions test/collections/config/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,76 @@ describe('Testing of the collection.config namespace', () => {
});
});

requireAtLeast(1, 37, 0).describe('dropVectorIndex', () => {
it('should drop default vector index from a collection', async () => {
const collectionName = 'TestDropDefaultVectorIndex';
const collection = await client.collections.create({
name: collectionName,
vectorizers: weaviate.configure.vectors.selfProvided({
vectorIndexConfig: weaviate.configure.vectorIndex.hnsw(),
}),
});

let config = await collection.config.get();
expect(config.vectorizers.default.indexType).toEqual('hnsw');

await collection.config.dropVectorIndex();

config = await collection.config.get();
expect(config.vectorizers.default.indexType).toEqual('none');
});

it('should throw an error when trying to drop a non-existent named vector index', async () => {
const collectionName = 'TestDropNonExistentNamedVectorIndex';
const collection = await client.collections.create({
name: collectionName,
vectorizers: weaviate.configure.vectors.selfProvided({
name: 'existing',
vectorIndexConfig: weaviate.configure.vectorIndex.hnsw(),
}),
});

await expect(collection.config.dropVectorIndex('nonexistent')).rejects.toThrow(
'The request to Weaviate failed with status code: 422 and message: {"error":[{"message":"not found: vector index \\"nonexistent\\" not found in class \\"TestDropNonExistentNamedVectorIndex\\""}]}'
Comment on lines +1117 to +1118
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the client generally throws errors on the 200+ HTTP codes? If yes, then it seems like this test is redundant, it essentially tests the server's response to a non-existen input. If no, then let's not assert the contents of the message -- someone may re-phrase that in v1.38 or sth and fail the client pipeline (used to happen a lot in the Java client test suite)

);

// Ensure existing vector index is still intact
const config = await collection.config.get();
expect(config.vectorizers.existing.indexType).toEqual('hnsw');
});

it('should drop named vector index from a collection with generics', async () => {
type TestDropVectorIndexVectors = {
one: number[];
two: number[];
};
const collectionName = 'TestDropNamedVectorIndex';
const collection = await client.collections.create<any, string, TestDropVectorIndexVectors>({
name: collectionName,
vectorizers: [
weaviate.configure.vectors.selfProvided({
name: 'one',
vectorIndexConfig: weaviate.configure.vectorIndex.hnsw(),
}),
weaviate.configure.vectors.selfProvided({
name: 'two',
vectorIndexConfig: weaviate.configure.vectorIndex.hnsw(),
}),
],
});

let config = await collection.config.get();
expect(config.vectorizers.one.indexType).toEqual('hnsw');
expect(config.vectorizers.two.indexType).toEqual('hnsw');

await collection.config.dropVectorIndex('one');

config = await collection.config.get();
expect(config.vectorizers.one.indexType).toEqual('none');
expect(config.vectorizers.two.indexType).toEqual('hnsw');
});
});

requireAtLeast(1, 35, 0).it('should create and update Object TTL configuration', async () => {
const collectionName = 'TestObjectTTL';
const collection = await client.collections.create({
Expand Down
Loading