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
29 changes: 20 additions & 9 deletions src/collections/config/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { WeaviateInvalidInputError } from '../../errors.js';
import {
WeaviateClass,
WeaviateInvertedIndexConfig,
WeaviateMultiTenancyConfig,
WeaviateReplicationConfig,
WeaviateVectorIndexConfig,
WeaviateVectorsConfig,
} from '../../openapi/types.js';
import { QuantizerGuards } from '../configure/parsing.js';
import {
InvertedIndexConfigUpdate,
MultiTenancyConfigUpdate,
ReplicationConfigUpdate,
VectorConfigUpdate,
VectorIndexConfigFlatUpdate,
Expand All @@ -30,6 +32,11 @@ export class MergeWithExisting {
current.invertedIndexConfig,
update.invertedIndex
);
if (update.multiTenancy !== undefined)
current.multiTenancyConfig = MergeWithExisting.multiTenancy(
current.multiTenancyConfig,
update.multiTenancy
);
if (update.replication !== undefined)
current.replicationConfig = MergeWithExisting.replication(
current.replicationConfig!,
Expand All @@ -56,7 +63,7 @@ export class MergeWithExisting {

static invertedIndex(
current: WeaviateInvertedIndexConfig,
update?: InvertedIndexConfigUpdate
update: InvertedIndexConfigUpdate
): WeaviateInvertedIndexConfig {
if (current === undefined) throw Error('Inverted index config is missing from the class schema.');
if (update === undefined) return current;
Expand All @@ -67,21 +74,27 @@ export class MergeWithExisting {
return merged;
}

static multiTenancy(
current: WeaviateMultiTenancyConfig,
update: MultiTenancyConfigUpdate
): MultiTenancyConfigUpdate {
if (current === undefined) throw Error('Multi-tenancy config is missing from the class schema.');
return { ...current, ...update };
}

static replication(
current: WeaviateReplicationConfig,
update?: ReplicationConfigUpdate
update: ReplicationConfigUpdate
): WeaviateReplicationConfig {
if (current === undefined) throw Error('Replication config is missing from the class schema.');
if (update === undefined) return current;
return { ...current, ...update };
}

static vectors(
current: WeaviateVectorsConfig,
update?: VectorConfigUpdate<string, VectorIndexType>[]
update: VectorConfigUpdate<string, VectorIndexType>[]
): WeaviateVectorsConfig {
if (current === undefined) throw Error('Vector index config is missing from the class schema.');
if (update === undefined) return current;
update.forEach((v) => {
const existing = current[v.name];
if (existing !== undefined) {
Expand All @@ -96,9 +109,8 @@ export class MergeWithExisting {

static flat(
current: WeaviateVectorIndexConfig,
update?: VectorIndexConfigFlatUpdate
update: VectorIndexConfigFlatUpdate
): WeaviateVectorIndexConfig {
if (update === undefined) return current;
if (
(QuantizerGuards.isPQUpdate(update.quantizer) && (current?.bq as any).enabled) ||
(QuantizerGuards.isBQUpdate(update.quantizer) && (current?.pq as any).enabled)
Expand All @@ -115,9 +127,8 @@ export class MergeWithExisting {

static hnsw(
current: WeaviateVectorIndexConfig,
update?: VectorIndexConfigHNSWUpdate
update: VectorIndexConfigHNSWUpdate
): WeaviateVectorIndexConfig {
if (update === undefined) return current;
if (
(QuantizerGuards.isBQUpdate(update.quantizer) &&
(((current?.pq as any) || {}).enabled || ((current?.sq as any) || {}).enabled)) ||
Expand Down
40 changes: 38 additions & 2 deletions src/collections/config/integration.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { WeaviateUnsupportedFeatureError } from '../../errors.js';
import weaviate, { WeaviateClient, weaviateV2 } from '../../index.js';
import { PropertyConfig, VectorIndexConfigDynamic, VectorIndexConfigHNSW } from './types/index.js';
import {
MultiTenancyConfig,
PropertyConfig,
VectorIndexConfigDynamic,
VectorIndexConfigHNSW,
} from './types/index.js';

const fail = (msg: string) => {
throw new Error(msg);
Expand Down Expand Up @@ -509,7 +514,7 @@ describe('Testing of the collection.config namespace', () => {
});

it('should be able to create and get a collection with multi-tenancy enabled', async () => {
const collectionName = 'TestCollectionConfigMultiTenancy';
const collectionName = 'TestCollectionConfigCreateGetMultiTenancy';
const collection = await client.collections.create({
name: collectionName,
multiTenancy: weaviate.configure.multiTenancy({
Expand All @@ -529,6 +534,37 @@ describe('Testing of the collection.config namespace', () => {
expect(config.multiTenancy.enabled).toEqual(true);
});

it('should be able to create and update a collection with multi-tenancy enabled', async () => {
const collectionName = 'TestCollectionConfigCreateUpdateMultiTenancy';
const collection = await client.collections.create({
name: collectionName,
multiTenancy: weaviate.configure.multiTenancy(),
});
let config = await collection.config.get();
expect(config.multiTenancy).toEqual<MultiTenancyConfig>({
enabled: true,
autoTenantActivation: false,
autoTenantCreation: false,
});

await collection.config.update({
multiTenancy: weaviate.reconfigure.multiTenancy({
autoTenantActivation: true,
autoTenantCreation: true,
}),
});
config = await collection.config.get();

expect(config.name).toEqual(collectionName);
expect(config.multiTenancy.autoTenantActivation).toEqual(
await client.getWeaviateVersion().then((ver) => !ver.isLowerThan(1, 25, 2))
);
expect(config.multiTenancy.autoTenantCreation).toEqual(
await client.getWeaviateVersion().then((ver) => !ver.isLowerThan(1, 25, 0))
);
expect(config.multiTenancy.enabled).toEqual(true);
});

it('should be able update the config of a collection with legacy vectors', async () => {
const clientV2 = weaviateV2.client({
host: 'http://localhost:8080',
Expand Down
2 changes: 2 additions & 0 deletions src/collections/config/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './vectorizer.js';

import {
InvertedIndexConfigUpdate,
MultiTenancyConfigUpdate,
ReplicationConfigUpdate,
VectorConfigUpdate,
} from '../../configure/types/index.js';
Expand Down Expand Up @@ -103,6 +104,7 @@ export type CollectionConfig = {
export type CollectionConfigUpdate = {
description?: string;
invertedIndex?: InvertedIndexConfigUpdate;
multiTenancy?: MultiTenancyConfigUpdate;
replication?: ReplicationConfigUpdate;
vectorizers?:
| VectorConfigUpdate<undefined, VectorIndexType>
Expand Down
24 changes: 23 additions & 1 deletion src/collections/config/unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { WeaviateInvertedIndexConfig, WeaviateVectorsConfig } from '../../openapi/types';
import {
WeaviateInvertedIndexConfig,
WeaviateMultiTenancyConfig,
WeaviateVectorsConfig,
} from '../../openapi/types';
import { MergeWithExisting } from './classes';

describe('Unit testing of the MergeWithExisting class', () => {
Expand Down Expand Up @@ -112,6 +116,12 @@ describe('Unit testing of the MergeWithExisting class', () => {
},
};

const multiTenancyConfig: WeaviateMultiTenancyConfig = {
enabled: true,
autoTenantActivation: false,
autoTenantCreation: false,
};

it('should merge a partial invertedIndexUpdate with existing schema', () => {
const merged = MergeWithExisting.invertedIndex(JSON.parse(JSON.stringify(invertedIndex)), {
bm25: {
Expand Down Expand Up @@ -341,4 +351,16 @@ describe('Unit testing of the MergeWithExisting class', () => {
},
});
});

it('should merge full multi tenancy config with existing schema', () => {
const merged = MergeWithExisting.multiTenancy(JSON.parse(JSON.stringify(multiTenancyConfig)), {
autoTenantActivation: true,
autoTenantCreation: true,
});
expect(merged).toEqual({
enabled: true,
autoTenantActivation: true,
autoTenantCreation: true,
});
});
});
27 changes: 23 additions & 4 deletions src/collections/configure/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
InvertedIndexConfigCreate,
InvertedIndexConfigUpdate,
MultiTenancyConfigCreate,
MultiTenancyConfigUpdate,
ReplicationConfigCreate,
ReplicationConfigUpdate,
ReplicationDeletionStrategy,
Expand Down Expand Up @@ -223,13 +224,13 @@ const reconfigure = {
},
},
/**
* Create a `ReplicationConfigUpdate` object to be used when defining the replication configuration of Weaviate.
* Create a `ReplicationConfigUpdate` object to be used when updating the replication configuration of Weaviate.
*
* See [the docs](https://weaviate.io/developers/weaviate/concepts/replication-architecture#replication-vs-sharding) for more details.
*
* @param {boolean} [options.asyncEnabled] Whether asynchronous replication is enabled.
* @param {ReplicationDeletionStrategy} [options.deletionStrategy] The deletion strategy when replication conflicts are detected between deletes and reads.
* @param {number} [options.factor] The replication factor.
* @param {boolean} [options.asyncEnabled] Whether to enable asynchronous replication.
* @param {ReplicationDeletionStrategy} [options.deletionStrategy] The deletion strategy to update when replication conflicts are detected between deletes and reads.
* @param {number} [options.factor] The replication factor to update.
*/
replication: (options: {
asyncEnabled?: boolean;
Expand All @@ -242,6 +243,24 @@ const reconfigure = {
factor: options.factor,
};
},
/**
* Create a `MultiTenancyConfigUpdate` object to be used when updating the multi-tenancy configuration of Weaviate.
*
* Note: You cannot update a single-tenant collection to become a multi-tenant collection. You must instead create a new multi-tenant collection and migrate the data over manually.
*
* @param {boolean} [options.autoTenantActivation] Whether to enable auto-tenant activation.
* @param {boolean} [options.autoTenantCreation] Whether to enable auto-tenant creation.
*
*/
multiTenancy: (options: {
autoTenantActivation?: boolean;
autoTenantCreation?: boolean;
}): MultiTenancyConfigUpdate => {
return {
autoTenantActivation: options.autoTenantActivation,
autoTenantCreation: options.autoTenantCreation,
};
},
};

export {
Expand Down
5 changes: 5 additions & 0 deletions src/collections/configure/types/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export type InvertedIndexConfigUpdate = {

export type MultiTenancyConfigCreate = RecursivePartial<MultiTenancyConfig>;

export type MultiTenancyConfigUpdate = {
autoTenantActivation?: boolean;
autoTenantCreation?: boolean;
};

export type NestedPropertyCreate<T = undefined> = T extends undefined
? {
name: string;
Expand Down
Loading