Skip to content

Commit c110e4c

Browse files
committed
Merge branch 'main' of https://github.com/weaviate/typescript-client into 1.29/colbert-multivector-support
2 parents b8e048d + 05aea41 commit c110e4c

File tree

14 files changed

+485
-111
lines changed

14 files changed

+485
-111
lines changed

.github/workflows/main.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ env:
1414
WEAVIATE_128: 1.28.11
1515
WEAVIATE_129: 1.29.1
1616
WEAVIATE_130: 1.30.1
17+
WEAVIATE_131: 1.31.0
1718

1819
concurrency:
1920
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}

src/collections/config/index.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import { WeaviateShardStatus } from '../../openapi/types.js';
44
import ClassUpdater from '../../schema/classUpdater.js';
55
import { ClassGetter, PropertyCreator, ShardUpdater } from '../../schema/index.js';
66
import ShardsGetter from '../../schema/shardsGetter.js';
7+
import VectorAdder from '../../schema/vectorAdder.js';
78
import { DbVersionSupport } from '../../utils/dbVersion.js';
89
import {
910
PropertyConfigCreate,
1011
ReferenceMultiTargetConfigCreate,
1112
ReferenceSingleTargetConfigCreate,
13+
VectorizersConfigAdd,
1214
} from '../configure/types/index.js';
1315
import { MergeWithExisting } from './classes.js';
1416
import {
@@ -23,7 +25,7 @@ import {
2325
VectorIndexConfigFlat,
2426
VectorIndexConfigHNSW,
2527
} from './types/index.js';
26-
import { classToCollection, resolveProperty, resolveReference } from './utils.js';
28+
import { classToCollection, makeVectorsConfig, resolveProperty, resolveReference } from './utils.js';
2729

2830
const config = <T>(
2931
connection: Connection,
@@ -47,6 +49,11 @@ const config = <T>(
4749
.withProperty(resolveReference<any>(reference))
4850
.do()
4951
.then(() => {}),
52+
addVector: async (vectors: VectorizersConfigAdd<T>) => {
53+
const supportsDynamicVectorIndex = await dbVersionSupport.supportsDynamicVectorIndex();
54+
const { vectorsConfig } = makeVectorsConfig(vectors, supportsDynamicVectorIndex);
55+
return new VectorAdder(connection).withClassName(name).withVectors(vectorsConfig).do();
56+
},
5057
get: () => getRaw().then(classToCollection<T>),
5158
getShards: () => {
5259
let builder = new ShardsGetter(connection).withClassName(name);
@@ -114,6 +121,17 @@ export interface Config<T> {
114121
addReference: (
115122
reference: ReferenceSingleTargetConfigCreate<T> | ReferenceMultiTargetConfigCreate<T>
116123
) => Promise<void>;
124+
/**
125+
* Add one or more named vectors to the collection in Weaviate.
126+
* Named vectors can be added to collections with existing named vectors only.
127+
*
128+
* Existing named vectors are immutable in Weaviate. The client will not include
129+
* any of those in the request.
130+
*
131+
* @param {VectorizersConfigAdd<any>} vectors Vector configurations.
132+
* @returns {Promise<void>} A promise that resolves when the named vector has been created.
133+
*/
134+
addVector: (vectors: VectorizersConfigAdd<T>) => Promise<void>;
117135
/**
118136
* Get the configuration for this collection from Weaviate.
119137
*

src/collections/config/integration.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* eslint-disable @typescript-eslint/no-non-null-assertion */
2+
import { requireAtLeast } from '../../../test/version.js';
23
import { WeaviateUnsupportedFeatureError } from '../../errors.js';
34
import weaviate, { WeaviateClient, weaviateV2 } from '../../index.js';
45
import {
@@ -388,6 +389,43 @@ describe('Testing of the collection.config namespace', () => {
388389
]);
389390
});
390391

392+
requireAtLeast(
393+
1,
394+
31,
395+
0
396+
)('Mutable named vectors', () => {
397+
it('should be able to add named vectors to a collection', async () => {
398+
const collectionName = 'TestCollectionConfigAddVector' as const;
399+
const collection = await client.collections.create({
400+
name: collectionName,
401+
vectorizers: weaviate.configure.vectorizer.none(),
402+
});
403+
// Add a single named vector
404+
await collection.config.addVector(weaviate.configure.vectorizer.none({ name: 'vector-a' }));
405+
406+
// Add several named vectors
407+
await collection.config.addVector([
408+
weaviate.configure.vectorizer.none({ name: 'vector-b' }),
409+
weaviate.configure.vectorizer.none({ name: 'vector-c' }),
410+
]);
411+
412+
// Trying to update 'default' vector -- should be omitted from request.
413+
await collection.config.addVector(
414+
weaviate.configure.vectorizer.none({
415+
name: 'default',
416+
vectorIndexConfig: weaviate.configure.vectorIndex.flat(),
417+
})
418+
);
419+
420+
const config = await collection.config.get();
421+
expect(config.vectorizers).toHaveProperty('vector-a');
422+
expect(config.vectorizers).toHaveProperty('vector-b');
423+
expect(config.vectorizers).toHaveProperty('vector-c');
424+
425+
expect(config.vectorizers.default).toHaveProperty('indexType', 'hnsw');
426+
});
427+
});
428+
391429
it('should get the shards of a sharded collection', async () => {
392430
const shards = await client.collections
393431
.create({

src/collections/config/utils.ts

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { WeaviateDeserializationError } from '../../errors.js';
1+
import {
2+
WeaviateDeserializationError,
3+
WeaviateInvalidInputError,
4+
WeaviateUnsupportedFeatureError,
5+
} from '../../errors.js';
26
import {
37
WeaviateBM25Config,
48
WeaviateClass,
@@ -13,11 +17,18 @@ import {
1317
WeaviateVectorIndexConfig,
1418
WeaviateVectorsConfig,
1519
} from '../../openapi/types.js';
20+
import { DbVersionSupport } from '../../utils/dbVersion.js';
21+
import { QuantizerGuards, VectorIndexGuards } from '../configure/parsing.js';
1622
import {
1723
PropertyConfigCreate,
1824
ReferenceConfigCreate,
1925
ReferenceMultiTargetConfigCreate,
2026
ReferenceSingleTargetConfigCreate,
27+
VectorIndexConfigCreate,
28+
VectorIndexConfigFlatCreate,
29+
VectorIndexConfigHNSWCreate,
30+
VectorizersConfigAdd,
31+
VectorizersConfigCreate,
2132
} from '../configure/types/index.js';
2233
import {
2334
BQConfig,
@@ -47,6 +58,7 @@ import {
4758
VectorIndexConfigHNSW,
4859
VectorIndexConfigType,
4960
VectorIndexFilterStrategy,
61+
VectorIndexType,
5062
VectorizerConfig,
5163
} from './types/index.js';
5264

@@ -124,6 +136,100 @@ export const classToCollection = <T>(cls: WeaviateClass): CollectionConfig => {
124136
};
125137
};
126138

139+
export const parseVectorIndex = (module: ModuleConfig<VectorIndexType, VectorIndexConfigCreate>): any => {
140+
if (module.config === undefined) return undefined;
141+
if (VectorIndexGuards.isDynamic(module.config)) {
142+
const { hnsw, flat, ...conf } = module.config;
143+
return {
144+
...conf,
145+
hnsw: parseVectorIndex({ name: 'hnsw', config: hnsw }),
146+
flat: parseVectorIndex({ name: 'flat', config: flat }),
147+
};
148+
}
149+
150+
let multiVector;
151+
if (VectorIndexGuards.isHNSW(module.config) && module.config.multiVector !== undefined) {
152+
multiVector = {
153+
...module.config.multiVector,
154+
enabled: true,
155+
};
156+
}
157+
158+
const { quantizer, ...conf } = module.config as
159+
| VectorIndexConfigFlatCreate
160+
| VectorIndexConfigHNSWCreate
161+
| Record<string, any>;
162+
if (quantizer === undefined) return conf;
163+
if (QuantizerGuards.isBQCreate(quantizer)) {
164+
const { type, ...quant } = quantizer;
165+
return {
166+
...conf,
167+
bq: {
168+
...quant,
169+
enabled: true,
170+
},
171+
};
172+
}
173+
if (QuantizerGuards.isPQCreate(quantizer)) {
174+
const { type, ...quant } = quantizer;
175+
return {
176+
...conf,
177+
pq: {
178+
...quant,
179+
enabled: true,
180+
},
181+
};
182+
}
183+
};
184+
185+
export const parseVectorizerConfig = (config?: VectorizerConfig): any => {
186+
if (config === undefined) return {};
187+
const { vectorizeCollectionName, ...rest } = config as any;
188+
return {
189+
...rest,
190+
vectorizeClassName: vectorizeCollectionName,
191+
};
192+
};
193+
194+
export const makeVectorsConfig = (
195+
configVectorizers: VectorizersConfigCreate<any, any> | VectorizersConfigAdd<any>,
196+
supportsDynamicVectorIndex: Awaited<ReturnType<DbVersionSupport['supportsDynamicVectorIndex']>>
197+
) => {
198+
let vectorizers: string[] = [];
199+
const vectorsConfig: Record<string, any> = {};
200+
const vectorizersConfig = Array.isArray(configVectorizers)
201+
? configVectorizers
202+
: [
203+
{
204+
...configVectorizers,
205+
name: configVectorizers.name || 'default',
206+
},
207+
];
208+
vectorizersConfig.forEach((v) => {
209+
if (v.vectorIndex.name === 'dynamic' && !supportsDynamicVectorIndex.supports) {
210+
throw new WeaviateUnsupportedFeatureError(supportsDynamicVectorIndex.message);
211+
}
212+
const vectorConfig: any = {
213+
vectorIndexConfig: parseVectorIndex(v.vectorIndex),
214+
vectorIndexType: v.vectorIndex.name,
215+
vectorizer: {},
216+
};
217+
const vectorizer = v.vectorizer.name === 'text2vec-azure-openai' ? 'text2vec-openai' : v.vectorizer.name;
218+
vectorizers = [...vectorizers, vectorizer];
219+
vectorConfig.vectorizer[vectorizer] = {
220+
properties: v.properties,
221+
...parseVectorizerConfig(v.vectorizer.config),
222+
};
223+
if (v.name === undefined) {
224+
throw new WeaviateInvalidInputError(
225+
'vectorName is required for each vectorizer when specifying more than one vectorizer'
226+
);
227+
}
228+
vectorsConfig[v.name] = vectorConfig;
229+
});
230+
return { vectorsConfig, vectorizers };
231+
};
232+
127233
function populated<T>(v: T | null | undefined): v is T {
128234
return v !== undefined && v !== null;
129235
}

src/collections/configure/types/vectorizer.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,16 @@ export type VectorConfigUpdate<N extends string | undefined, I extends VectorInd
5656

5757
export type VectorizersConfigCreate<T, V> = V extends undefined
5858
?
59-
| VectorConfigCreate<PrimitiveKeys<T>, undefined, VectorIndexType, Vectorizer>
59+
| VectorConfigCreate<PrimitiveKeys<T>, string | undefined, VectorIndexType, Vectorizer>
6060
| VectorConfigCreate<PrimitiveKeys<T>, string, VectorIndexType, Vectorizer>[]
6161
:
62-
| VectorConfigCreate<PrimitiveKeys<T>, undefined, VectorIndexType, Vectorizer>
62+
| VectorConfigCreate<PrimitiveKeys<T>, (keyof V & string) | undefined, VectorIndexType, Vectorizer>
6363
| VectorConfigCreate<PrimitiveKeys<T>, keyof V & string, VectorIndexType, Vectorizer>[];
6464

65+
export type VectorizersConfigAdd<T> =
66+
| VectorConfigCreate<PrimitiveKeys<T>, string, VectorIndexType, Vectorizer>
67+
| VectorConfigCreate<PrimitiveKeys<T>, string, VectorIndexType, Vectorizer>[];
68+
6569
export type ConfigureNonTextVectorizerOptions<
6670
N extends string | undefined,
6771
I extends VectorIndexType,

0 commit comments

Comments
 (0)