ydb-qdrant 2.2.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,4 +3,4 @@ export declare const YDB_ENDPOINT: string;
3
3
  export declare const YDB_DATABASE: string;
4
4
  export declare const PORT: number;
5
5
  export declare const LOG_LEVEL: string;
6
- export declare const APPROX_PRESELECT: number;
6
+ export declare const VECTOR_INDEX_BUILD_ENABLED: boolean;
@@ -3,6 +3,18 @@ export const YDB_ENDPOINT = process.env.YDB_ENDPOINT ?? "";
3
3
  export const YDB_DATABASE = process.env.YDB_DATABASE ?? "";
4
4
  export const PORT = process.env.PORT ? Number(process.env.PORT) : 8080;
5
5
  export const LOG_LEVEL = process.env.LOG_LEVEL ?? "info";
6
- export const APPROX_PRESELECT = process.env.APPROX_PRESELECT
7
- ? Math.max(1, Math.min(5000, Number(process.env.APPROX_PRESELECT)))
8
- : 1000;
6
+ function parseBooleanEnv(value, defaultValue) {
7
+ if (value === undefined) {
8
+ return defaultValue;
9
+ }
10
+ const normalized = value.trim().toLowerCase();
11
+ if (normalized === "" ||
12
+ normalized === "0" ||
13
+ normalized === "false" ||
14
+ normalized === "no" ||
15
+ normalized === "off") {
16
+ return false;
17
+ }
18
+ return true;
19
+ }
20
+ export const VECTOR_INDEX_BUILD_ENABLED = parseBooleanEnv(process.env.VECTOR_INDEX_BUILD_ENABLED, false);
@@ -2,6 +2,7 @@ import { TypedValues, withSession } from "../ydb/client.js";
2
2
  import { buildJsonOrEmpty, buildVectorParam } from "../ydb/helpers.js";
3
3
  import { logger } from "../logging/logger.js";
4
4
  import { notifyUpsert } from "../indexing/IndexScheduler.js";
5
+ import { VECTOR_INDEX_BUILD_ENABLED } from "../config/env.js";
5
6
  export async function upsertPoints(tableName, points, vectorType, dimension) {
6
7
  let upserted = 0;
7
8
  await withSession(async (s) => {
@@ -76,26 +77,34 @@ export async function searchPoints(tableName, queryVector, top, withPayload, dis
76
77
  LIMIT $k2;
77
78
  `;
78
79
  let rs;
79
- try {
80
- // Try with vector index first
81
- rs = await withSession(async (s) => {
82
- return await s.executeQuery(buildQuery(true), params);
83
- });
84
- logger.info({ tableName }, "vector index found; using index for search");
85
- }
86
- catch (e) {
87
- const msg = e instanceof Error ? e.message : String(e);
88
- // Fallback to table scan if index not found or not ready
89
- if (/not found|does not exist|no such index|no global index|is not ready to use/i.test(msg)) {
90
- logger.info({ tableName }, "vector index not available (missing or building); falling back to table scan");
80
+ if (VECTOR_INDEX_BUILD_ENABLED) {
81
+ try {
82
+ // Try with vector index first
91
83
  rs = await withSession(async (s) => {
92
- return await s.executeQuery(buildQuery(false), params);
84
+ return await s.executeQuery(buildQuery(true), params);
93
85
  });
86
+ logger.info({ tableName }, "vector index found; using index for search");
94
87
  }
95
- else {
96
- throw e;
88
+ catch (e) {
89
+ const msg = e instanceof Error ? e.message : String(e);
90
+ const indexUnavailable = /not found|does not exist|no such index|no global index|is not ready to use/i.test(msg);
91
+ if (indexUnavailable) {
92
+ logger.info({ tableName }, "vector index not available (missing or building); falling back to table scan");
93
+ rs = await withSession(async (s) => {
94
+ return await s.executeQuery(buildQuery(false), params);
95
+ });
96
+ }
97
+ else {
98
+ throw e;
99
+ }
97
100
  }
98
101
  }
102
+ else {
103
+ // Vector index usage disabled: always use table scan
104
+ rs = await withSession(async (s) => {
105
+ return await s.executeQuery(buildQuery(false), params);
106
+ });
107
+ }
99
108
  const rowset = rs.resultSets?.[0];
100
109
  const rows = (rowset?.rows ?? []);
101
110
  return rows.map((row) => {
@@ -5,6 +5,7 @@ import { createCollection as repoCreateCollection, deleteCollection as repoDelet
5
5
  import { deletePoints as repoDeletePoints, searchPoints as repoSearchPoints, upsertPoints as repoUpsertPoints, } from "../repositories/pointsRepo.js";
6
6
  import { requestIndexBuild } from "../indexing/IndexScheduler.js";
7
7
  import { logger } from "../logging/logger.js";
8
+ import { VECTOR_INDEX_BUILD_ENABLED } from "../config/env.js";
8
9
  export class QdrantServiceError extends Error {
9
10
  statusCode;
10
11
  payload;
@@ -87,6 +88,7 @@ export async function deleteCollection(ctx) {
87
88
  await repoDeleteCollection(normalized.metaKey);
88
89
  return { acknowledged: true };
89
90
  }
91
+ let loggedIndexBuildDisabled = false;
90
92
  function isNumberArray(value) {
91
93
  return Array.isArray(value) && value.every((x) => typeof x === "number");
92
94
  }
@@ -213,7 +215,13 @@ export async function upsertPoints(ctx, body) {
213
215
  });
214
216
  }
215
217
  const upserted = await repoUpsertPoints(meta.table, parsed.data.points, meta.vectorType, meta.dimension);
216
- requestIndexBuild(meta.table, meta.dimension, meta.distance, meta.vectorType);
218
+ if (VECTOR_INDEX_BUILD_ENABLED) {
219
+ requestIndexBuild(meta.table, meta.dimension, meta.distance, meta.vectorType);
220
+ }
221
+ else if (!loggedIndexBuildDisabled) {
222
+ logger.info({ table: meta.table }, "vector index building disabled by env; skipping automatic emb_idx rebuilds");
223
+ loggedIndexBuildDisabled = true;
224
+ }
217
225
  return { upserted };
218
226
  }
219
227
  async function executeSearch(ctx, normalizedSearch, source) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-qdrant",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "main": "dist/package/Api.js",
5
5
  "types": "dist/package/Api.d.ts",
6
6
  "exports": {
@@ -16,7 +16,7 @@
16
16
  "scripts": {
17
17
  "test": "vitest run --exclude \"test/integration/**\"",
18
18
  "test:coverage": "vitest run --coverage --exclude \"test/integration/**\"",
19
- "test:integration": "vitest run test/integration/YdbRealIntegration.test.ts",
19
+ "test:integration": "VECTOR_INDEX_BUILD_ENABLED=false vitest run test/integration/YdbRealIntegration.index-disabled.test.ts && VECTOR_INDEX_BUILD_ENABLED=true vitest run test/integration/YdbRealIntegration.test.ts",
20
20
  "build": "tsc -p tsconfig.json",
21
21
  "typecheck": "tsc -p tsconfig.json --noEmit",
22
22
  "dev": "tsx watch src/index.ts",