diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 5ebb76b8..5e70eab5 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -15,7 +15,7 @@ env: WEAVIATE_129: 1.29.8 WEAVIATE_130: 1.30.7 WEAVIATE_131: 1.31.0 - WEAVIATE_132: 1.32.0-rc.1 + WEAVIATE_132: 1.32.4-cdf9a3b concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} diff --git a/src/collections/config/index.ts b/src/collections/config/index.ts index bdc7ed4e..a8850d17 100644 --- a/src/collections/config/index.ts +++ b/src/collections/config/index.ts @@ -21,6 +21,7 @@ import { QuantizerConfig, RQConfig, SQConfig, + UncompressedConfig, VectorIndexConfig, VectorIndexConfigDynamic, VectorIndexConfigFlat, @@ -184,6 +185,9 @@ export class VectorIndex { } export class Quantizer { + static isUncompressed(config?: QuantizerConfig): config is UncompressedConfig { + return config?.type === 'none'; + } static isPQ(config?: QuantizerConfig): config is PQConfig { return config?.type === 'pq'; } diff --git a/src/collections/config/types/vectorIndex.ts b/src/collections/config/types/vectorIndex.ts index b9c894cf..907fdc08 100644 --- a/src/collections/config/types/vectorIndex.ts +++ b/src/collections/config/types/vectorIndex.ts @@ -68,6 +68,10 @@ export type RQConfig = { type: 'rq'; }; +export type UncompressedConfig = { + type: 'none'; +}; + export type MultiVectorConfig = { aggregation: 'maxSim' | string; encoding?: MultiVectorEncodingConfig; @@ -98,4 +102,4 @@ export type VectorIndexFilterStrategy = 'sweeping' | 'acorn'; export type VectorIndexConfig = VectorIndexConfigHNSW | VectorIndexConfigFlat | VectorIndexConfigDynamic; -export type QuantizerConfig = PQConfig | BQConfig | SQConfig | RQConfig; +export type QuantizerConfig = PQConfig | BQConfig | SQConfig | RQConfig | UncompressedConfig; diff --git a/src/collections/config/utils.ts b/src/collections/config/utils.ts index 76104422..b87d8c16 100644 --- a/src/collections/config/utils.ts +++ b/src/collections/config/utils.ts @@ -30,6 +30,7 @@ import { VectorizersConfigAdd, VectorizersConfigCreate, } from '../configure/types/index.js'; +import { Quantizer } from '../index.js'; import { BQConfig, CollectionConfig, @@ -179,6 +180,12 @@ export const parseVectorIndex = (module: ModuleConfig { }); }); + it('should create an hnsw VectorIndexConfig type with "none" quantizer', () => { + const config = configure.vectorIndex.hnsw({ + quantizer: configure.vectorIndex.quantizer.none(), + }); + expect(config).toEqual>({ + name: 'hnsw', + config: { + quantizer: { + type: 'none', + }, + type: 'hnsw', + }, + }); + }); + it('should create an hnsw VectorIndexConfig type with multivector enabled', () => { const config = configure.vectorIndex.hnsw({ multiVector: configure.vectorIndex.multiVector.multiVector({ aggregation: 'maxSim' }), diff --git a/src/collections/configure/vectorIndex.ts b/src/collections/configure/vectorIndex.ts index 83f0eac9..39bd8af3 100644 --- a/src/collections/configure/vectorIndex.ts +++ b/src/collections/configure/vectorIndex.ts @@ -2,6 +2,7 @@ import { ModuleConfig, PQEncoderDistribution, PQEncoderType, + UncompressedConfig, VectorIndexFilterStrategy, } from '../config/types/index.js'; import { @@ -149,6 +150,14 @@ const configure = { * Define the quantizer configuration to use when creating a vector index. */ quantizer: { + /** + * Create an object of type `UncomplressedConfig` to skip default vector quantization. + * + * @returns {BQConfigCreate} The object of type `BQConfigCreate`. + */ + none: (): UncompressedConfig => { + return { type: 'none' }; + }, /** * Create an object of type `BQConfigCreate` to be used when defining the quantizer configuration of a vector index. * diff --git a/src/collections/integration.test.ts b/src/collections/integration.test.ts index 905f83ce..193d8bec 100644 --- a/src/collections/integration.test.ts +++ b/src/collections/integration.test.ts @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { requireAtLeast } from '../../test/version'; import weaviate, { WeaviateClient } from '../index'; import { CollectionConfigCreate, @@ -656,6 +657,45 @@ describe('Testing of the collections.create method', () => { ).toEqual(true); }); + requireAtLeast(1, 32, 0).describe('uncompressed vectors', () => { + it('should be able to create a collection with uncompressed default vector', async () => { + const collectionName = 'TestCollectionUncompressedVector'; + + await contextionary.collections.create({ + name: collectionName, + vectorizers: weaviate.configure.vectors.text2VecContextionary({ + vectorIndexConfig: weaviate.configure.vectorIndex.hnsw({ + quantizer: weaviate.configure.vectorIndex.quantizer.none(), + }), + }), + }); + + const collection = await contextionary.collections.export(collectionName); + + expect((collection.vectorizers.default.indexConfig as VectorIndexConfigHNSW).quantizer).toBeUndefined(); + }); + + it('should be able to create a collection with uncompressed named vector', async () => { + const collectionName = 'TestCollectionUncompressedVectorNamed'; + + await contextionary.collections.create({ + name: collectionName, + vectorizers: weaviate.configure.vectors.text2VecContextionary({ + name: 'custom_vec', + vectorIndexConfig: weaviate.configure.vectorIndex.hnsw({ + quantizer: weaviate.configure.vectorIndex.quantizer.none(), + }), + }), + }); + + const collection = await contextionary.collections.export(collectionName); + + expect( + (collection.vectorizers.custom_vec.indexConfig as VectorIndexConfigHNSW).quantizer + ).toBeUndefined(); + }); + }); + it('should be able to create a collection with an openai vectorizer with configure.vectors', async () => { const collectionName = 'TestCollectionOpenAIVectorizerWithConfigureVectorizer'; const response = await openai.collections