Skip to content
Open
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
3 changes: 0 additions & 3 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ jobs:
npm ci
ci/run_dependencies.sh ${{ matrix.versions.weaviate }}
- name: "Run tests without authentication tests"
env:
DEFAULT_VECTOR_INDEX: hfresh
run: WEAVIATE_VERSION=${{ matrix.versions.weaviate }} npm test
- name: "Transpile the package"
run: npm run build
Expand Down Expand Up @@ -100,7 +98,6 @@ jobs:
WCS_DUMMY_CI_PW: ${{ secrets.WCS_DUMMY_CI_PW }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
OKTA_CLIENT_SECRET: ${{ secrets.OKTA_CLIENT_SECRET }}
DEFAULT_VECTOR_INDEX: hfresh
run: WEAVIATE_VERSION=${{ matrix.versions.weaviate }} npm test
- name: "Stop Weaviate"
run: ci/stop_dependencies.sh ${{ matrix.versions.weaviate }}
Expand Down
1 change: 1 addition & 0 deletions ci/docker-compose-openai.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ services:
ENABLE_MODULES: 'text2vec-openai,generative-openai'
CLUSTER_HOSTNAME: 'node1'
DISABLE_TELEMETRY: 'true'
DEFAULT_VECTOR_INDEX: 'hfresh'
...
1 change: 1 addition & 0 deletions ci/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ services:
AUTOSCHEMA_ENABLED: "false"
IMAGE_INFERENCE_API: "http://i2v-neural:8080"
DISABLE_TELEMETRY: "true"
DEFAULT_VECTOR_INDEX: "hfresh"
OBJECTS_TTL_DELETE_SCHEDULE: "@hourly"
contextionary:
environment:
Expand Down
4 changes: 2 additions & 2 deletions src/collections/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ const config = <T>(
.then(() => {}),
addVector: async (vectors: VectorizersConfigAdd<T>) => {
const { vectorsConfig } = makeVectorsConfig(vectors);
const { supports: serverAppliesDefaultVIT } =
const { supports: serverAppliesDefaultVectorIndexType } =
await dbVersionSupport.supportsServerSideDefaultVectorIndexType();
if (!serverAppliesDefaultVIT && vectorsConfig) {
if (!serverAppliesDefaultVectorIndexType && vectorsConfig) {
for (const v of Object.values(vectorsConfig)) {
if (!(v as any).vectorIndexType) (v as any).vectorIndexType = 'hnsw';
}
Expand Down
33 changes: 14 additions & 19 deletions src/collections/configure/unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1256,12 +1256,9 @@ describe('Unit testing of the vectorizer factory class', () => {

it('should create the correct Text2VecDigitalOceanConfig type with only the required model', () => {
const config = configure.vectors.text2VecDigitalOcean({ model: 'qwen3-embedding-0.6b' });
expect(config).toEqual<VectorConfigCreate<never, undefined, 'hnsw', 'text2vec-digitalocean'>>({
name: undefined,
vectorIndex: {
name: 'hnsw',
config: undefined,
},
expect(config).toMatchObject<
Partial<VectorConfigCreate<never, undefined, 'hnsw', 'text2vec-digitalocean'>>
>({
vectorizer: {
name: 'text2vec-digitalocean',
config: {
Expand All @@ -1277,20 +1274,18 @@ describe('Unit testing of the vectorizer factory class', () => {
name: 'test',
model: 'qwen3-embedding-0.6b',
});
expect(config).toEqual<VectorConfigCreate<never, 'test', 'hnsw', 'text2vec-digitalocean'>>({
name: 'test',
vectorIndex: {
name: 'hnsw',
config: undefined,
},
vectorizer: {
name: 'text2vec-digitalocean',
config: {
baseURL: 'https://inference.do-ai.run',
model: 'qwen3-embedding-0.6b',
expect(config).toMatchObject<Partial<VectorConfigCreate<never, 'test', 'hnsw', 'text2vec-digitalocean'>>>(
{
name: 'test',
vectorizer: {
name: 'text2vec-digitalocean',
config: {
baseURL: 'https://inference.do-ai.run',
model: 'qwen3-embedding-0.6b',
},
},
},
});
}
);
});

it('should create the correct Text2VecOllamaConfig type with defaults', () => {
Expand Down
8 changes: 6 additions & 2 deletions src/utils/dbVersion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,19 @@ export class DbVersion {
}

static fromString = (version: string) => {
// CI image tags may append an architecture suffix (for example: 1.37.5.amd64).
// Strip that suffix before semver parsing.
const normalizedVersion = version.replace(/\.(amd64|arm64|x86_64)$/, '');

let regex = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
let match = version.match(regex);
let match = normalizedVersion.match(regex);
if (match) {
const [_, major, minor, patch] = match;
return new DbVersion(parseInt(major, 10), parseInt(minor, 10), parseInt(patch, 10));
}

regex = /^v?(\d+)\.(\d+)$/;
match = version.match(regex);
match = normalizedVersion.match(regex);
if (match) {
const [_, major, minor] = match;
return new DbVersion(parseInt(major, 10), parseInt(minor, 10));
Expand Down
120 changes: 77 additions & 43 deletions test/collections/config/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,24 @@ import weaviate, {
weaviateV2,
} from '../../../src/index.js';
import { WeaviateClass } from '../../../src/openapi/types.js';
import { DbVersion } from '../../../src/utils/dbVersion.js';
import { requireAtLeast } from '../../../test/version.js';

/**
* Helper to determine expected default vector index type based on server version.
* On versions >= 1.37.5 with DEFAULT_VECTOR_INDEX=hfresh, the server defaults to hfresh.
*/
function expectedDefaultIndexType(version: DbVersion): 'hnsw' | 'hfresh' {
return version.isAtLeast(1, 37, 5) ? 'hfresh' : 'hnsw';
}

describe('Testing of the collection.config namespace', () => {
let client: WeaviateClient;
let serverVersion: DbVersion;

beforeAll(async () => {
client = await weaviate.connectToLocal();
serverVersion = await client.getWeaviateVersion();
});

afterAll(() => client.collections.deleteAll());
Expand Down Expand Up @@ -61,26 +72,35 @@ describe('Testing of the collection.config namespace', () => {
]);
expect(config.generative).toBeUndefined();
expect(config.reranker).toBeUndefined();
expect(config.vectorizers.default.indexConfig).toEqual<VectorIndexConfigHNSW>({
skip: false,
cleanupIntervalSeconds: 300,
maxConnections: (await client.getWeaviateVersion().then((ver) => ver.isLowerThan(1, 26, 0))) ? 64 : 32,
efConstruction: 128,
ef: -1,
dynamicEfMin: 100,
dynamicEfMax: 500,
dynamicEfFactor: 8,
vectorCacheMaxObjects: 1000000000000,
filterStrategy: (await client.getWeaviateVersion().then((ver) => ver.isLowerThan(1, 34, 0)))
? 'sweeping'
: 'acorn',
flatSearchCutoff: 40000,
distance: 'cosine',
multiVector: undefined,
quantizer: undefined,
type: 'hnsw',
});
expect(config.vectorizers.default.indexType).toEqual('hnsw');
const expectedIndexType = expectedDefaultIndexType(serverVersion);
if (expectedIndexType === 'hfresh') {
expect(config.vectorizers.default.indexConfig).toMatchObject<Partial<VectorIndexConfigHFresh>>({
distance: 'cosine',
maxPostingSizeKb: 48,
replicas: 4,
searchProbe: 64,
type: 'hfresh',
});
} else {
expect(config.vectorizers.default.indexConfig).toEqual<VectorIndexConfigHNSW>({
skip: false,
cleanupIntervalSeconds: 300,
maxConnections: serverVersion.isLowerThan(1, 26, 0) ? 64 : 32,
efConstruction: 128,
ef: -1,
dynamicEfMin: 100,
dynamicEfMax: 500,
dynamicEfFactor: 8,
vectorCacheMaxObjects: 1000000000000,
filterStrategy: serverVersion.isLowerThan(1, 34, 0) ? 'sweeping' : 'acorn',
flatSearchCutoff: 40000,
distance: 'cosine',
multiVector: undefined,
quantizer: undefined,
type: 'hnsw',
});
}
expect(config.vectorizers.default.indexType).toEqual(expectedIndexType);
expect(config.vectorizers.default.vectorizer.name).toEqual('none');
});

Expand Down Expand Up @@ -119,26 +139,35 @@ describe('Testing of the collection.config namespace', () => {
]);
expect(config.generative).toBeUndefined();
expect(config.reranker).toBeUndefined();
expect(config.vectorizers.default.indexConfig).toEqual<VectorIndexConfigHNSW>({
skip: false,
cleanupIntervalSeconds: 300,
maxConnections: (await client.getWeaviateVersion().then((ver) => ver.isLowerThan(1, 26, 0))) ? 64 : 32,
efConstruction: 128,
ef: -1,
dynamicEfMin: 100,
dynamicEfMax: 500,
dynamicEfFactor: 8,
vectorCacheMaxObjects: 1000000000000,
filterStrategy: (await client.getWeaviateVersion().then((ver) => ver.isLowerThan(1, 34, 0)))
? 'sweeping'
: 'acorn',
flatSearchCutoff: 40000,
distance: 'cosine',
multiVector: undefined,
quantizer: undefined,
type: 'hnsw',
});
expect(config.vectorizers.default.indexType).toEqual('hnsw');
const expectedIndexType2 = expectedDefaultIndexType(serverVersion);
if (expectedIndexType2 === 'hfresh') {
expect(config.vectorizers.default.indexConfig).toMatchObject<Partial<VectorIndexConfigHFresh>>({
distance: 'cosine',
maxPostingSizeKb: 48,
replicas: 4,
searchProbe: 64,
type: 'hfresh',
});
} else {
expect(config.vectorizers.default.indexConfig).toEqual<VectorIndexConfigHNSW>({
skip: false,
cleanupIntervalSeconds: 300,
maxConnections: serverVersion.isLowerThan(1, 26, 0) ? 64 : 32,
efConstruction: 128,
ef: -1,
dynamicEfMin: 100,
dynamicEfMax: 500,
dynamicEfFactor: 8,
vectorCacheMaxObjects: 1000000000000,
filterStrategy: serverVersion.isLowerThan(1, 34, 0) ? 'sweeping' : 'acorn',
flatSearchCutoff: 40000,
distance: 'cosine',
multiVector: undefined,
quantizer: undefined,
type: 'hnsw',
});
}
expect(config.vectorizers.default.indexType).toEqual(expectedIndexType2);
expect(config.vectorizers.default.vectorizer.name).toEqual('none');
});

Expand Down Expand Up @@ -188,7 +217,7 @@ describe('Testing of the collection.config namespace', () => {
);
expect(config.properties[1].vectorizerConfig?.['text2vec-contextionary'].skip).toEqual(false);
expect(config.vectorizers.title.indexConfig).toBeDefined();
expect(config.vectorizers.title.indexType).toEqual('hnsw');
expect(config.vectorizers.title.indexType).toEqual(expectedDefaultIndexType(serverVersion));
expect(config.vectorizers.title.properties).toEqual(['title']);
expect(config.vectorizers.title.vectorizer.name).toEqual('text2vec-contextionary');
});
Expand Down Expand Up @@ -598,7 +627,7 @@ describe('Testing of the collection.config namespace', () => {
expect(config.vectorizers).toHaveProperty('vector-b');
expect(config.vectorizers).toHaveProperty('vector-c');

expect(config.vectorizers.default).toHaveProperty('indexType', 'hnsw');
expect(config.vectorizers.default).toHaveProperty('indexType', expectedDefaultIndexType(serverVersion));
});
});

Expand Down Expand Up @@ -676,7 +705,10 @@ describe('Testing of the collection.config namespace', () => {
dataType: 'text',
},
],
vectorizers: weaviate.configure.vectors.none(),
// Explicitly use hnsw to allow reconfiguration with hnsw options
vectorizers: weaviate.configure.vectors.none({
vectorIndexConfig: weaviate.configure.vectorIndex.hnsw(),
}),
});
const supportsUpdatingPropertyDescriptions = await client
.getWeaviateVersion()
Expand Down Expand Up @@ -821,6 +853,8 @@ describe('Testing of the collection.config namespace', () => {
.withClass({
class: collectionName,
vectorizer: 'none',
// Explicitly use hnsw to allow reconfiguration with hnsw options
vectorIndexType: 'hnsw',
})
.do();
const collection = client.collections.use(collectionName);
Expand Down
Loading
Loading