@bhushanpawar/sqldb 1.0.6 → 1.0.7
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.
- package/dist/cache/cache-manager.d.ts +18 -1
- package/dist/cache/cache-manager.d.ts.map +1 -1
- package/dist/cache/cache-manager.js +76 -2
- package/dist/cache/cache-manager.js.map +1 -1
- package/dist/cli/index.js +0 -0
- package/dist/client.d.ts +54 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +124 -1
- package/dist/client.js.map +1 -1
- package/dist/connection/mariadb.d.ts +15 -0
- package/dist/connection/mariadb.d.ts.map +1 -1
- package/dist/connection/mariadb.js +25 -0
- package/dist/connection/mariadb.js.map +1 -1
- package/dist/discovery/relationship-parser.d.ts.map +1 -1
- package/dist/discovery/relationship-parser.js +8 -1
- package/dist/discovery/relationship-parser.js.map +1 -1
- package/dist/discovery/schema-reader.d.ts +2 -0
- package/dist/discovery/schema-reader.d.ts.map +1 -1
- package/dist/discovery/schema-reader.js +91 -0
- package/dist/discovery/schema-reader.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/query/operations.d.ts +35 -1
- package/dist/query/operations.d.ts.map +1 -1
- package/dist/query/operations.js +307 -4
- package/dist/query/operations.js.map +1 -1
- package/dist/query/query-tracker.d.ts +30 -0
- package/dist/query/query-tracker.d.ts.map +1 -1
- package/dist/query/query-tracker.js +86 -1
- package/dist/query/query-tracker.js.map +1 -1
- package/dist/search/inverted-index-manager.d.ts +76 -0
- package/dist/search/inverted-index-manager.d.ts.map +1 -0
- package/dist/search/inverted-index-manager.js +371 -0
- package/dist/search/inverted-index-manager.js.map +1 -0
- package/dist/search/search-ranker.d.ts +91 -0
- package/dist/search/search-ranker.d.ts.map +1 -0
- package/dist/search/search-ranker.js +281 -0
- package/dist/search/search-ranker.js.map +1 -0
- package/dist/search/tokenizer.d.ts +80 -0
- package/dist/search/tokenizer.d.ts.map +1 -0
- package/dist/search/tokenizer.js +398 -0
- package/dist/search/tokenizer.js.map +1 -0
- package/dist/types/cache.d.ts +16 -0
- package/dist/types/cache.d.ts.map +1 -1
- package/dist/types/cache.js.map +1 -1
- package/dist/types/config.d.ts +10 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +13 -1
- package/dist/types/config.js.map +1 -1
- package/dist/types/query.d.ts +4 -0
- package/dist/types/query.d.ts.map +1 -1
- package/dist/types/schema.d.ts +35 -0
- package/dist/types/schema.d.ts.map +1 -1
- package/dist/types/search.d.ts +223 -0
- package/dist/types/search.d.ts.map +1 -0
- package/dist/types/search.js +54 -0
- package/dist/types/search.js.map +1 -0
- package/dist/types/warming.d.ts +1 -1
- package/dist/types/warming.d.ts.map +1 -1
- package/dist/utils/case-converter.d.ts +38 -0
- package/dist/utils/case-converter.d.ts.map +1 -0
- package/dist/utils/case-converter.js +90 -0
- package/dist/utils/case-converter.js.map +1 -0
- package/dist/warming/auto-warming-manager.d.ts.map +1 -1
- package/dist/warming/auto-warming-manager.js +5 -0
- package/dist/warming/auto-warming-manager.js.map +1 -1
- package/package.json +7 -3
- package/dist/best-practice-example.d.ts +0 -35
- package/dist/best-practice-example.d.ts.map +0 -1
- package/dist/best-practice-example.js +0 -171
- package/dist/best-practice-example.js.map +0 -1
- package/dist/db-schema.d.ts +0 -413
- package/dist/db-schema.d.ts.map +0 -1
- package/dist/db-schema.js +0 -1149
- package/dist/db-schema.js.map +0 -1
- package/dist/demo-debug.d.ts +0 -2
- package/dist/demo-debug.d.ts.map +0 -1
- package/dist/demo-debug.js +0 -36
- package/dist/demo-debug.js.map +0 -1
- package/dist/smart-cache/cache/cache-key-builder.d.ts +0 -17
- package/dist/smart-cache/cache/cache-key-builder.d.ts.map +0 -1
- package/dist/smart-cache/cache/cache-key-builder.js +0 -100
- package/dist/smart-cache/cache/cache-key-builder.js.map +0 -1
- package/dist/smart-cache/cache/cache-manager.d.ts +0 -22
- package/dist/smart-cache/cache/cache-manager.d.ts.map +0 -1
- package/dist/smart-cache/cache/cache-manager.js +0 -124
- package/dist/smart-cache/cache/cache-manager.js.map +0 -1
- package/dist/smart-cache/cache/invalidation.d.ts +0 -15
- package/dist/smart-cache/cache/invalidation.d.ts.map +0 -1
- package/dist/smart-cache/cache/invalidation.js +0 -59
- package/dist/smart-cache/cache/invalidation.js.map +0 -1
- package/dist/smart-cache/client.d.ts +0 -36
- package/dist/smart-cache/client.d.ts.map +0 -1
- package/dist/smart-cache/client.js +0 -138
- package/dist/smart-cache/client.js.map +0 -1
- package/dist/smart-cache/connection/mariadb.d.ts +0 -14
- package/dist/smart-cache/connection/mariadb.d.ts.map +0 -1
- package/dist/smart-cache/connection/mariadb.js +0 -82
- package/dist/smart-cache/connection/mariadb.js.map +0 -1
- package/dist/smart-cache/connection/redis.d.ts +0 -20
- package/dist/smart-cache/connection/redis.d.ts.map +0 -1
- package/dist/smart-cache/connection/redis.js +0 -168
- package/dist/smart-cache/connection/redis.js.map +0 -1
- package/dist/smart-cache/discovery/dependency-graph.d.ts +0 -20
- package/dist/smart-cache/discovery/dependency-graph.d.ts.map +0 -1
- package/dist/smart-cache/discovery/dependency-graph.js +0 -89
- package/dist/smart-cache/discovery/dependency-graph.js.map +0 -1
- package/dist/smart-cache/discovery/relationship-parser.d.ts +0 -10
- package/dist/smart-cache/discovery/relationship-parser.d.ts.map +0 -1
- package/dist/smart-cache/discovery/relationship-parser.js +0 -40
- package/dist/smart-cache/discovery/relationship-parser.js.map +0 -1
- package/dist/smart-cache/discovery/schema-reader.d.ts +0 -15
- package/dist/smart-cache/discovery/schema-reader.d.ts.map +0 -1
- package/dist/smart-cache/discovery/schema-reader.js +0 -82
- package/dist/smart-cache/discovery/schema-reader.js.map +0 -1
- package/dist/smart-cache/examples/basic-usage.d.ts +0 -3
- package/dist/smart-cache/examples/basic-usage.d.ts.map +0 -1
- package/dist/smart-cache/examples/basic-usage.js +0 -105
- package/dist/smart-cache/examples/basic-usage.js.map +0 -1
- package/dist/smart-cache/examples/hooks-example.d.ts +0 -3
- package/dist/smart-cache/examples/hooks-example.d.ts.map +0 -1
- package/dist/smart-cache/examples/hooks-example.js +0 -133
- package/dist/smart-cache/examples/hooks-example.js.map +0 -1
- package/dist/smart-cache/examples/relationships-example.d.ts +0 -3
- package/dist/smart-cache/examples/relationships-example.d.ts.map +0 -1
- package/dist/smart-cache/examples/relationships-example.js +0 -88
- package/dist/smart-cache/examples/relationships-example.js.map +0 -1
- package/dist/smart-cache/hooks/hooks-manager.d.ts +0 -22
- package/dist/smart-cache/hooks/hooks-manager.d.ts.map +0 -1
- package/dist/smart-cache/hooks/hooks-manager.js +0 -117
- package/dist/smart-cache/hooks/hooks-manager.js.map +0 -1
- package/dist/smart-cache/index.d.ts +0 -19
- package/dist/smart-cache/index.d.ts.map +0 -1
- package/dist/smart-cache/index.js +0 -49
- package/dist/smart-cache/index.js.map +0 -1
- package/dist/smart-cache/query/operations.d.ts +0 -31
- package/dist/smart-cache/query/operations.d.ts.map +0 -1
- package/dist/smart-cache/query/operations.js +0 -187
- package/dist/smart-cache/query/operations.js.map +0 -1
- package/dist/smart-cache/query/query-builder.d.ts +0 -15
- package/dist/smart-cache/query/query-builder.d.ts.map +0 -1
- package/dist/smart-cache/query/query-builder.js +0 -169
- package/dist/smart-cache/query/query-builder.js.map +0 -1
- package/dist/smart-cache/query/table-proxy.d.ts +0 -11
- package/dist/smart-cache/query/table-proxy.d.ts.map +0 -1
- package/dist/smart-cache/query/table-proxy.js +0 -25
- package/dist/smart-cache/query/table-proxy.js.map +0 -1
- package/dist/smart-cache/types/cache.d.ts +0 -29
- package/dist/smart-cache/types/cache.d.ts.map +0 -1
- package/dist/smart-cache/types/cache.js +0 -10
- package/dist/smart-cache/types/cache.js.map +0 -1
- package/dist/smart-cache/types/config.d.ts +0 -47
- package/dist/smart-cache/types/config.d.ts.map +0 -1
- package/dist/smart-cache/types/config.js +0 -27
- package/dist/smart-cache/types/config.js.map +0 -1
- package/dist/smart-cache/types/query.d.ts +0 -36
- package/dist/smart-cache/types/query.d.ts.map +0 -1
- package/dist/smart-cache/types/query.js +0 -3
- package/dist/smart-cache/types/query.js.map +0 -1
- package/dist/smart-cache/types/schema.d.ts +0 -25
- package/dist/smart-cache/types/schema.d.ts.map +0 -1
- package/dist/smart-cache/types/schema.js +0 -3
- package/dist/smart-cache/types/schema.js.map +0 -1
- package/dist/trial.d.ts +0 -7
- package/dist/trial.d.ts.map +0 -1
- package/dist/trial.js +0 -30
- package/dist/trial.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-tracker.js","sourceRoot":"","sources":["../../src/query/query-tracker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"query-tracker.js","sourceRoot":"","sources":["../../src/query/query-tracker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoKA,0CAUC;AA7KD,+CAAiC;AAmBjC,MAAa,oBAAoB;IAK/B,YAAY,qBAA6B,IAAI;QAJrC,YAAO,GAAiC,IAAI,GAAG,EAAE,CAAC;QAClD,eAAU,GAAoB,EAAE,CAAC;QACjC,uBAAkB,GAAW,IAAI,CAAC,CAAC,KAAK;QAG9C,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED,UAAU,CAAC,QAAuB;QAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE/B,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;YAChE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,UAAU,CAAC,aAAsB;QAC/B,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;IAED,YAAY,CAAC,aAAsB;QACjC,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACnC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,aAAa,CACzC,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QACR,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAE5C,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,YAAY,EAAE,CAAC;gBACf,cAAc,EAAE,EAAE;gBAClB,kBAAkB,EAAE,EAAE;gBACtB,WAAW,EAAE,CAAC;gBACd,WAAW,EAAE,CAAC;gBACd,WAAW,EAAE,CAAC;gBACd,WAAW,EAAE,EAAE;gBACf,SAAS,EAAE,CAAC;gBACZ,WAAW,EAAE,CAAC;aACf,CAAC;QACJ,CAAC;QAED,MAAM,cAAc,GAA2B,EAAE,CAAC;QAClD,MAAM,kBAAkB,GAA2B,EAAE,CAAC;QACtD,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,MAAM,WAAW,GAKZ,EAAE,CAAC;QACR,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpC,iBAAiB;YACjB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpB,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAC/E,CAAC;YAED,qBAAqB;YACrB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpB,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACvF,CAAC;YAED,kBAAkB;YAClB,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;gBACxC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;gBAEtC,qBAAqB;gBACrB,IAAI,KAAK,CAAC,eAAe,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBACrD,WAAW,CAAC,IAAI,CAAC;wBACf,KAAK,EAAE,KAAK,CAAC,GAAG;wBAChB,QAAQ,EAAE,KAAK,CAAC,eAAe;wBAC/B,SAAS,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;wBACpC,SAAS,EAAE,KAAK,CAAC,SAAS;qBAC3B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,eAAe;YACf,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,WAAW,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC;YACtC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM;YAC7D,CAAC,CAAC,CAAC,CAAC;QACN,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtE,6CAA6C;QAC7C,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAEpD,MAAM,SAAS,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE5E,OAAO;YACL,YAAY;YACZ,cAAc;YACd,kBAAkB;YAClB,WAAW;YACX,WAAW;YACX,WAAW;YACX,WAAW,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,sBAAsB;YAC7D,SAAS;YACT,WAAW;SACZ,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,qBAAqB,CAAC,EAAU;QAC9B,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;IAC/B,CAAC;CACF;AA3ID,oDA2IC;AAED;;GAEG;AACH,SAAgB,eAAe;IAC7B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IACD,mCAAmC;IACnC,OAAO,sCAAsC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;QACnE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QAC1C,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inverted Index Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages inverted indexes stored in Redis for fast text search.
|
|
5
|
+
* An inverted index maps words → document IDs for instant lookup.
|
|
6
|
+
*
|
|
7
|
+
* Storage structure in Redis:
|
|
8
|
+
* - Key: "sqldb:index:{table}:word:{word}"
|
|
9
|
+
* - Value: Sorted Set [(docId, score), ...]
|
|
10
|
+
*
|
|
11
|
+
* - Key: "sqldb:index:{table}:doc:{docId}"
|
|
12
|
+
* - Value: Set [word1, word2, ...]
|
|
13
|
+
*
|
|
14
|
+
* - Key: "sqldb:index:{table}:meta"
|
|
15
|
+
* - Value: Hash { lastBuild, docCount, termCount }
|
|
16
|
+
*/
|
|
17
|
+
import { RedisConnectionManager } from '../connection/redis';
|
|
18
|
+
import { InvertedIndexConfig, IndexStats } from '../types/search';
|
|
19
|
+
export declare class InvertedIndexManager {
|
|
20
|
+
private redis;
|
|
21
|
+
private config;
|
|
22
|
+
private tokenizers;
|
|
23
|
+
private keyPrefix;
|
|
24
|
+
constructor(redis: RedisConnectionManager, config: InvertedIndexConfig, keyPrefix?: string);
|
|
25
|
+
/**
|
|
26
|
+
* Build inverted index for a table from scratch
|
|
27
|
+
*/
|
|
28
|
+
buildIndex(tableName: string, documents: Array<{
|
|
29
|
+
id: number;
|
|
30
|
+
[key: string]: any;
|
|
31
|
+
}>): Promise<IndexStats>;
|
|
32
|
+
/**
|
|
33
|
+
* Update index for a single document
|
|
34
|
+
*/
|
|
35
|
+
updateDocument(tableName: string, docId: string | number, data: Record<string, any>): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Delete document from index
|
|
38
|
+
*/
|
|
39
|
+
deleteDocument(tableName: string, docId: string | number): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Search for documents matching query terms
|
|
42
|
+
* Returns document IDs as strings (supports both numeric IDs and UUIDs)
|
|
43
|
+
*/
|
|
44
|
+
search(tableName: string, query: string, limit?: number): Promise<string[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Get document IDs for a specific term
|
|
47
|
+
*/
|
|
48
|
+
getDocumentsForTerm(tableName: string, term: string, limit?: number): Promise<string[]>;
|
|
49
|
+
/**
|
|
50
|
+
* Get statistics for an index
|
|
51
|
+
*/
|
|
52
|
+
getStats(tableName: string): Promise<IndexStats | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Clear entire index for a table
|
|
55
|
+
*/
|
|
56
|
+
clearIndex(tableName: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Get all indexed terms for a table
|
|
59
|
+
*/
|
|
60
|
+
getAllTerms(tableName: string, limit?: number): Promise<string[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Check if index exists for a table
|
|
63
|
+
*/
|
|
64
|
+
indexExists(tableName: string): Promise<boolean>;
|
|
65
|
+
private buildWordKey;
|
|
66
|
+
private buildDocKey;
|
|
67
|
+
private buildMetaKey;
|
|
68
|
+
private storeMetadata;
|
|
69
|
+
/**
|
|
70
|
+
* Extract document ID from a record
|
|
71
|
+
* Supports: id, {table}_id, or first field ending in '_id'
|
|
72
|
+
* Returns a string representation for Redis storage (works with both UUIDs and numbers)
|
|
73
|
+
*/
|
|
74
|
+
private extractDocumentId;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=inverted-index-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inverted-index-manager.d.ts","sourceRoot":"","sources":["../../src/search/inverted-index-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAiB,MAAM,iBAAiB,CAAC;AAGjF,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,SAAS,CAAS;gBAEd,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,mBAAmB,EAAE,SAAS,CAAC,EAAE,MAAM;IAmB1F;;OAEG;IACG,UAAU,CACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC,GACnD,OAAO,CAAC,UAAU,CAAC;IA2GtB;;OAEG;IACG,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACxB,OAAO,CAAC,IAAI,CAAC;IAuDhB;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B9E;;;OAGG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiDrF;;OAEG;IACG,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAYlG;;OAEG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAwB7D;;OAEG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAelD;;OAEG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAgB7E;;OAEG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOtD,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,YAAY;YAIN,aAAa;IAiB3B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;CA2B1B"}
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Inverted Index Manager
|
|
4
|
+
*
|
|
5
|
+
* Manages inverted indexes stored in Redis for fast text search.
|
|
6
|
+
* An inverted index maps words → document IDs for instant lookup.
|
|
7
|
+
*
|
|
8
|
+
* Storage structure in Redis:
|
|
9
|
+
* - Key: "sqldb:index:{table}:word:{word}"
|
|
10
|
+
* - Value: Sorted Set [(docId, score), ...]
|
|
11
|
+
*
|
|
12
|
+
* - Key: "sqldb:index:{table}:doc:{docId}"
|
|
13
|
+
* - Value: Set [word1, word2, ...]
|
|
14
|
+
*
|
|
15
|
+
* - Key: "sqldb:index:{table}:meta"
|
|
16
|
+
* - Value: Hash { lastBuild, docCount, termCount }
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.InvertedIndexManager = void 0;
|
|
20
|
+
const tokenizer_1 = require("./tokenizer");
|
|
21
|
+
class InvertedIndexManager {
|
|
22
|
+
constructor(redis, config, keyPrefix) {
|
|
23
|
+
this.tokenizers = new Map();
|
|
24
|
+
this.redis = redis;
|
|
25
|
+
this.config = config;
|
|
26
|
+
this.keyPrefix = keyPrefix || 'sqldb';
|
|
27
|
+
// Initialize tokenizers for each table
|
|
28
|
+
for (const [tableName, tableConfig] of Object.entries(config.tables)) {
|
|
29
|
+
this.tokenizers.set(tableName, new tokenizer_1.Tokenizer({
|
|
30
|
+
type: tableConfig.tokenizer,
|
|
31
|
+
minWordLength: tableConfig.minWordLength,
|
|
32
|
+
stopWords: tableConfig.stopWords,
|
|
33
|
+
caseSensitive: tableConfig.caseSensitive,
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build inverted index for a table from scratch
|
|
39
|
+
*/
|
|
40
|
+
async buildIndex(tableName, documents) {
|
|
41
|
+
const startTime = Date.now();
|
|
42
|
+
const tableConfig = this.config.tables[tableName];
|
|
43
|
+
if (!tableConfig) {
|
|
44
|
+
throw new Error(`No search configuration found for table: ${tableName}`);
|
|
45
|
+
}
|
|
46
|
+
const tokenizer = this.tokenizers.get(tableName);
|
|
47
|
+
if (!tokenizer) {
|
|
48
|
+
throw new Error(`No tokenizer found for table: ${tableName}`);
|
|
49
|
+
}
|
|
50
|
+
// Clear existing index
|
|
51
|
+
await this.clearIndex(tableName);
|
|
52
|
+
const client = this.redis.getClient();
|
|
53
|
+
if (!client) {
|
|
54
|
+
throw new Error('Redis client not connected');
|
|
55
|
+
}
|
|
56
|
+
let totalTerms = 0;
|
|
57
|
+
let totalTokens = 0;
|
|
58
|
+
const termFrequency = new Map(); // Track document frequency per term
|
|
59
|
+
// Build index for each document
|
|
60
|
+
for (const doc of documents) {
|
|
61
|
+
// Try to find the document ID (supports id, {table}_id, or any numeric primary key)
|
|
62
|
+
const docId = this.extractDocumentId(doc, tableName);
|
|
63
|
+
// Skip documents without an ID
|
|
64
|
+
if (docId === undefined || docId === null) {
|
|
65
|
+
console.warn(`Skipping document without ID in table ${tableName}:`, Object.keys(doc).join(', '));
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
// Tokenize all searchable fields
|
|
69
|
+
const tokens = (0, tokenizer_1.tokenizeFields)(tokenizer, doc, tableConfig.searchableFields);
|
|
70
|
+
totalTokens += tokens.length;
|
|
71
|
+
// Group tokens by term
|
|
72
|
+
const termMap = new Map();
|
|
73
|
+
for (const token of tokens) {
|
|
74
|
+
if (!termMap.has(token.term)) {
|
|
75
|
+
termMap.set(token.term, token);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// Merge positions
|
|
79
|
+
const existing = termMap.get(token.term);
|
|
80
|
+
existing.positions.push(...token.positions);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Store each term in Redis
|
|
84
|
+
const pipeline = client.pipeline();
|
|
85
|
+
for (const [term, metadata] of termMap.entries()) {
|
|
86
|
+
// Calculate term frequency for this document
|
|
87
|
+
const tf = metadata.positions.length;
|
|
88
|
+
// Field boost (if configured)
|
|
89
|
+
const fieldBoost = tableConfig.fieldBoosts?.[metadata.field] || 1.0;
|
|
90
|
+
// Combine TF and field boost for initial score
|
|
91
|
+
const score = tf * fieldBoost;
|
|
92
|
+
// Add to inverted index: term → [docId, score]
|
|
93
|
+
const wordKey = this.buildWordKey(tableName, term);
|
|
94
|
+
pipeline.zadd(wordKey, score, String(docId));
|
|
95
|
+
// Track document frequency
|
|
96
|
+
termFrequency.set(term, (termFrequency.get(term) || 0) + 1);
|
|
97
|
+
}
|
|
98
|
+
// Store document → terms mapping (for updates/deletes)
|
|
99
|
+
const docKey = this.buildDocKey(tableName, docId);
|
|
100
|
+
const terms = Array.from(termMap.keys());
|
|
101
|
+
if (terms.length > 0) {
|
|
102
|
+
pipeline.sadd(docKey, ...terms);
|
|
103
|
+
}
|
|
104
|
+
// Execute pipeline
|
|
105
|
+
await pipeline.exec();
|
|
106
|
+
}
|
|
107
|
+
// Store metadata
|
|
108
|
+
totalTerms = termFrequency.size;
|
|
109
|
+
await this.storeMetadata(tableName, {
|
|
110
|
+
tableName,
|
|
111
|
+
totalDocuments: documents.length,
|
|
112
|
+
totalTerms,
|
|
113
|
+
totalTokens,
|
|
114
|
+
lastBuildTime: Date.now(),
|
|
115
|
+
buildDurationMs: Date.now() - startTime,
|
|
116
|
+
fields: tableConfig.searchableFields,
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
tableName,
|
|
120
|
+
totalDocuments: documents.length,
|
|
121
|
+
totalTerms,
|
|
122
|
+
totalTokens,
|
|
123
|
+
lastBuildTime: Date.now(),
|
|
124
|
+
buildDurationMs: Date.now() - startTime,
|
|
125
|
+
fields: tableConfig.searchableFields,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Update index for a single document
|
|
130
|
+
*/
|
|
131
|
+
async updateDocument(tableName, docId, data) {
|
|
132
|
+
const tableConfig = this.config.tables[tableName];
|
|
133
|
+
if (!tableConfig) {
|
|
134
|
+
throw new Error(`No search configuration found for table: ${tableName}`);
|
|
135
|
+
}
|
|
136
|
+
const tokenizer = this.tokenizers.get(tableName);
|
|
137
|
+
if (!tokenizer) {
|
|
138
|
+
throw new Error(`No tokenizer found for table: ${tableName}`);
|
|
139
|
+
}
|
|
140
|
+
const client = this.redis.getClient();
|
|
141
|
+
if (!client) {
|
|
142
|
+
throw new Error('Redis client not connected');
|
|
143
|
+
}
|
|
144
|
+
// First, remove old document from index
|
|
145
|
+
await this.deleteDocument(tableName, docId);
|
|
146
|
+
// Tokenize new data
|
|
147
|
+
const tokens = (0, tokenizer_1.tokenizeFields)(tokenizer, data, tableConfig.searchableFields);
|
|
148
|
+
// Group tokens by term
|
|
149
|
+
const termMap = new Map();
|
|
150
|
+
for (const token of tokens) {
|
|
151
|
+
if (!termMap.has(token.term)) {
|
|
152
|
+
termMap.set(token.term, token);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const existing = termMap.get(token.term);
|
|
156
|
+
existing.positions.push(...token.positions);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Store each term in Redis
|
|
160
|
+
const pipeline = client.pipeline();
|
|
161
|
+
for (const [term, metadata] of termMap.entries()) {
|
|
162
|
+
const tf = metadata.positions.length;
|
|
163
|
+
const fieldBoost = tableConfig.fieldBoosts?.[metadata.field] || 1.0;
|
|
164
|
+
const score = tf * fieldBoost;
|
|
165
|
+
const wordKey = this.buildWordKey(tableName, term);
|
|
166
|
+
pipeline.zadd(wordKey, score, String(docId));
|
|
167
|
+
}
|
|
168
|
+
// Store document → terms mapping
|
|
169
|
+
const docKey = this.buildDocKey(tableName, docId);
|
|
170
|
+
const terms = Array.from(termMap.keys());
|
|
171
|
+
if (terms.length > 0) {
|
|
172
|
+
pipeline.sadd(docKey, ...terms);
|
|
173
|
+
}
|
|
174
|
+
await pipeline.exec();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Delete document from index
|
|
178
|
+
*/
|
|
179
|
+
async deleteDocument(tableName, docId) {
|
|
180
|
+
const client = this.redis.getClient();
|
|
181
|
+
if (!client) {
|
|
182
|
+
throw new Error('Redis client not connected');
|
|
183
|
+
}
|
|
184
|
+
// Get all terms for this document
|
|
185
|
+
const docKey = this.buildDocKey(tableName, docId);
|
|
186
|
+
const terms = await client.smembers(docKey);
|
|
187
|
+
if (terms.length === 0) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Remove document from each term's sorted set
|
|
191
|
+
const pipeline = client.pipeline();
|
|
192
|
+
for (const term of terms) {
|
|
193
|
+
const wordKey = this.buildWordKey(tableName, term);
|
|
194
|
+
pipeline.zrem(wordKey, String(docId));
|
|
195
|
+
}
|
|
196
|
+
// Delete document key
|
|
197
|
+
pipeline.del(docKey);
|
|
198
|
+
await pipeline.exec();
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Search for documents matching query terms
|
|
202
|
+
* Returns document IDs as strings (supports both numeric IDs and UUIDs)
|
|
203
|
+
*/
|
|
204
|
+
async search(tableName, query, limit = 10) {
|
|
205
|
+
const tableConfig = this.config.tables[tableName];
|
|
206
|
+
if (!tableConfig) {
|
|
207
|
+
throw new Error(`No search configuration found for table: ${tableName}`);
|
|
208
|
+
}
|
|
209
|
+
const tokenizer = this.tokenizers.get(tableName);
|
|
210
|
+
if (!tokenizer) {
|
|
211
|
+
throw new Error(`No tokenizer found for table: ${tableName}`);
|
|
212
|
+
}
|
|
213
|
+
const client = this.redis.getClient();
|
|
214
|
+
if (!client) {
|
|
215
|
+
throw new Error('Redis client not connected');
|
|
216
|
+
}
|
|
217
|
+
// Tokenize query
|
|
218
|
+
const tokens = tokenizer.tokenize(query);
|
|
219
|
+
if (tokens.length === 0) {
|
|
220
|
+
return [];
|
|
221
|
+
}
|
|
222
|
+
const terms = tokenizer.getUniqueTerms(tokens);
|
|
223
|
+
// If single term, just get documents for that term
|
|
224
|
+
if (terms.length === 1) {
|
|
225
|
+
const wordKey = this.buildWordKey(tableName, terms[0]);
|
|
226
|
+
const results = await client.zrevrange(wordKey, 0, limit - 1);
|
|
227
|
+
return results; // Already strings
|
|
228
|
+
}
|
|
229
|
+
// Multiple terms: use Redis ZINTERSTORE for intersection
|
|
230
|
+
const tempKey = `${this.keyPrefix}:temp:search:${Date.now()}`;
|
|
231
|
+
const wordKeys = terms.map(term => this.buildWordKey(tableName, term));
|
|
232
|
+
try {
|
|
233
|
+
// Intersect all term keys (documents must contain ALL terms)
|
|
234
|
+
await client.zinterstore(tempKey, terms.length, ...wordKeys, 'AGGREGATE', 'SUM');
|
|
235
|
+
// Get top results
|
|
236
|
+
const results = await client.zrevrange(tempKey, 0, limit - 1);
|
|
237
|
+
return results; // Already strings
|
|
238
|
+
}
|
|
239
|
+
finally {
|
|
240
|
+
// Clean up temp key
|
|
241
|
+
await client.del(tempKey);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get document IDs for a specific term
|
|
246
|
+
*/
|
|
247
|
+
async getDocumentsForTerm(tableName, term, limit = 100) {
|
|
248
|
+
const client = this.redis.getClient();
|
|
249
|
+
if (!client) {
|
|
250
|
+
return [];
|
|
251
|
+
}
|
|
252
|
+
const wordKey = this.buildWordKey(tableName, term);
|
|
253
|
+
const results = await client.zrevrange(wordKey, 0, limit - 1);
|
|
254
|
+
return results; // Already strings
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Get statistics for an index
|
|
258
|
+
*/
|
|
259
|
+
async getStats(tableName) {
|
|
260
|
+
const client = this.redis.getClient();
|
|
261
|
+
if (!client) {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
const metaKey = this.buildMetaKey(tableName);
|
|
265
|
+
const meta = await client.hgetall(metaKey);
|
|
266
|
+
if (!meta || Object.keys(meta).length === 0) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
tableName,
|
|
271
|
+
totalDocuments: parseInt(meta.totalDocuments || '0', 10),
|
|
272
|
+
totalTerms: parseInt(meta.totalTerms || '0', 10),
|
|
273
|
+
totalTokens: parseInt(meta.totalTokens || '0', 10),
|
|
274
|
+
lastBuildTime: parseInt(meta.lastBuildTime || '0', 10),
|
|
275
|
+
buildDurationMs: parseInt(meta.buildDurationMs || '0', 10),
|
|
276
|
+
fields: meta.fields ? JSON.parse(meta.fields) : [],
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Clear entire index for a table
|
|
281
|
+
*/
|
|
282
|
+
async clearIndex(tableName) {
|
|
283
|
+
const client = this.redis.getClient();
|
|
284
|
+
if (!client) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
// Delete all keys matching the table pattern
|
|
288
|
+
const pattern = `${this.keyPrefix}:index:${tableName}:*`;
|
|
289
|
+
const keys = await this.redis.scan(pattern);
|
|
290
|
+
if (keys.length > 0) {
|
|
291
|
+
await client.del(...keys);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Get all indexed terms for a table
|
|
296
|
+
*/
|
|
297
|
+
async getAllTerms(tableName, limit = 1000) {
|
|
298
|
+
const client = this.redis.getClient();
|
|
299
|
+
if (!client) {
|
|
300
|
+
return [];
|
|
301
|
+
}
|
|
302
|
+
const pattern = `${this.keyPrefix}:index:${tableName}:word:*`;
|
|
303
|
+
const keys = await this.redis.scan(pattern);
|
|
304
|
+
// Extract term from key
|
|
305
|
+
const prefix = `${this.keyPrefix}:index:${tableName}:word:`;
|
|
306
|
+
const terms = keys.map(key => key.substring(prefix.length)).slice(0, limit);
|
|
307
|
+
return terms;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Check if index exists for a table
|
|
311
|
+
*/
|
|
312
|
+
async indexExists(tableName) {
|
|
313
|
+
const stats = await this.getStats(tableName);
|
|
314
|
+
return stats !== null && stats.totalDocuments > 0;
|
|
315
|
+
}
|
|
316
|
+
// ========== Private Helper Methods ==========
|
|
317
|
+
buildWordKey(tableName, term) {
|
|
318
|
+
return `${this.keyPrefix}:index:${tableName}:word:${term}`;
|
|
319
|
+
}
|
|
320
|
+
buildDocKey(tableName, docId) {
|
|
321
|
+
return `${this.keyPrefix}:index:${tableName}:doc:${docId}`;
|
|
322
|
+
}
|
|
323
|
+
buildMetaKey(tableName) {
|
|
324
|
+
return `${this.keyPrefix}:index:${tableName}:meta`;
|
|
325
|
+
}
|
|
326
|
+
async storeMetadata(tableName, stats) {
|
|
327
|
+
const client = this.redis.getClient();
|
|
328
|
+
if (!client) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
const metaKey = this.buildMetaKey(tableName);
|
|
332
|
+
await client.hset(metaKey, {
|
|
333
|
+
totalDocuments: stats.totalDocuments.toString(),
|
|
334
|
+
totalTerms: stats.totalTerms.toString(),
|
|
335
|
+
totalTokens: stats.totalTokens.toString(),
|
|
336
|
+
lastBuildTime: stats.lastBuildTime.toString(),
|
|
337
|
+
buildDurationMs: stats.buildDurationMs.toString(),
|
|
338
|
+
fields: JSON.stringify(stats.fields),
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Extract document ID from a record
|
|
343
|
+
* Supports: id, {table}_id, or first field ending in '_id'
|
|
344
|
+
* Returns a string representation for Redis storage (works with both UUIDs and numbers)
|
|
345
|
+
*/
|
|
346
|
+
extractDocumentId(doc, tableName) {
|
|
347
|
+
// Try 'id' first
|
|
348
|
+
if (doc.id !== undefined && doc.id !== null) {
|
|
349
|
+
return String(doc.id);
|
|
350
|
+
}
|
|
351
|
+
// Try '{table}_id' (e.g., service_id, user_id)
|
|
352
|
+
const tableIdField = `${tableName.replace(/s$/, '')}_id`; // services → service_id
|
|
353
|
+
if (doc[tableIdField] !== undefined && doc[tableIdField] !== null) {
|
|
354
|
+
return String(doc[tableIdField]);
|
|
355
|
+
}
|
|
356
|
+
// Try exact table name with _id
|
|
357
|
+
const exactTableIdField = `${tableName}_id`;
|
|
358
|
+
if (doc[exactTableIdField] !== undefined && doc[exactTableIdField] !== null) {
|
|
359
|
+
return String(doc[exactTableIdField]);
|
|
360
|
+
}
|
|
361
|
+
// As last resort, find first field that ends with '_id'
|
|
362
|
+
for (const key of Object.keys(doc)) {
|
|
363
|
+
if (key.endsWith('_id') && doc[key] !== undefined && doc[key] !== null) {
|
|
364
|
+
return String(doc[key]);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return undefined;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
exports.InvertedIndexManager = InvertedIndexManager;
|
|
371
|
+
//# sourceMappingURL=inverted-index-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inverted-index-manager.js","sourceRoot":"","sources":["../../src/search/inverted-index-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Ranker
|
|
3
|
+
*
|
|
4
|
+
* Implements ranking algorithms for search results:
|
|
5
|
+
* - TF-IDF (Term Frequency - Inverse Document Frequency)
|
|
6
|
+
* - Field boosting (title matches rank higher than description)
|
|
7
|
+
* - Proximity scoring (words closer together rank higher)
|
|
8
|
+
* - Freshness scoring (newer documents rank higher - optional)
|
|
9
|
+
*/
|
|
10
|
+
import { ScoringContext, RankingWeights, SearchResult, TokenMetadata } from '../types/search';
|
|
11
|
+
import { Tokenizer } from './tokenizer';
|
|
12
|
+
export declare class SearchRanker {
|
|
13
|
+
private weights;
|
|
14
|
+
constructor(weights?: Partial<RankingWeights>);
|
|
15
|
+
/**
|
|
16
|
+
* Calculate TF-IDF score for a term in a document
|
|
17
|
+
*
|
|
18
|
+
* TF (Term Frequency): How often does the term appear in this document?
|
|
19
|
+
* IDF (Inverse Document Frequency): How rare is this term across all documents?
|
|
20
|
+
*
|
|
21
|
+
* Formula: TF-IDF = TF * IDF
|
|
22
|
+
* where:
|
|
23
|
+
* TF = (term frequency in document) / (total terms in document)
|
|
24
|
+
* IDF = log((total documents) / (documents containing term))
|
|
25
|
+
*/
|
|
26
|
+
calculateTfIdf(context: ScoringContext): number;
|
|
27
|
+
/**
|
|
28
|
+
* Calculate field boost score
|
|
29
|
+
* Fields with higher boost values rank better
|
|
30
|
+
*/
|
|
31
|
+
calculateFieldBoost(fieldBoost: number): number;
|
|
32
|
+
/**
|
|
33
|
+
* Calculate proximity score
|
|
34
|
+
* Documents where query terms appear close together rank higher
|
|
35
|
+
*/
|
|
36
|
+
calculateProximityScore(proximityScore?: number): number;
|
|
37
|
+
/**
|
|
38
|
+
* Calculate freshness score (optional)
|
|
39
|
+
* Newer documents rank higher
|
|
40
|
+
*/
|
|
41
|
+
calculateFreshnessScore(createdAt?: number, decayDays?: number): number;
|
|
42
|
+
/**
|
|
43
|
+
* Calculate combined score for a document
|
|
44
|
+
*/
|
|
45
|
+
calculateScore(context: ScoringContext): number;
|
|
46
|
+
/**
|
|
47
|
+
* Rank search results by relevance
|
|
48
|
+
*/
|
|
49
|
+
rankResults<T>(results: Array<{
|
|
50
|
+
docId: number;
|
|
51
|
+
data: T;
|
|
52
|
+
}>, queryTerms: string[], termStats: Map<string, {
|
|
53
|
+
docFrequency: number;
|
|
54
|
+
termFrequenciesByDoc: Map<number, number>;
|
|
55
|
+
}>, totalDocs: number, fieldBoosts?: Record<string, number>, proximityScores?: Map<number, number>): SearchResult<T>[];
|
|
56
|
+
/**
|
|
57
|
+
* Get average field boost value
|
|
58
|
+
*/
|
|
59
|
+
private getAverageFieldBoost;
|
|
60
|
+
/**
|
|
61
|
+
* Calculate BM25 score (more advanced than TF-IDF)
|
|
62
|
+
*
|
|
63
|
+
* BM25 is a ranking function used by search engines.
|
|
64
|
+
* It's an improvement over TF-IDF with better handling of:
|
|
65
|
+
* - Document length normalization
|
|
66
|
+
* - Term saturation (diminishing returns for high TF)
|
|
67
|
+
*
|
|
68
|
+
* Formula: BM25 = IDF * (TF * (k1 + 1)) / (TF + k1 * (1 - b + b * (docLen / avgDocLen)))
|
|
69
|
+
* where:
|
|
70
|
+
* k1 = term frequency saturation parameter (typical: 1.2-2.0)
|
|
71
|
+
* b = length normalization parameter (typical: 0.75)
|
|
72
|
+
*/
|
|
73
|
+
calculateBM25(termFrequency: number, docFrequency: number, totalDocs: number, docLength: number, avgDocLength: number, k1?: number, b?: number): number;
|
|
74
|
+
/**
|
|
75
|
+
* Highlight search terms in text
|
|
76
|
+
*/
|
|
77
|
+
highlightText(text: string, terms: string[], preTag?: string, postTag?: string, tokenizer?: Tokenizer): string;
|
|
78
|
+
/**
|
|
79
|
+
* Generate text snippet with highlighted terms
|
|
80
|
+
*/
|
|
81
|
+
generateSnippet(text: string, terms: string[], maxLength?: number, preTag?: string, postTag?: string): string;
|
|
82
|
+
/**
|
|
83
|
+
* Calculate proximity between multiple terms in a document
|
|
84
|
+
*/
|
|
85
|
+
calculateMultiTermProximity(tokens: TokenMetadata[], queryTerms: string[]): number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Helper function to create ranker with custom weights
|
|
89
|
+
*/
|
|
90
|
+
export declare function createRanker(weights?: Partial<RankingWeights>): SearchRanker;
|
|
91
|
+
//# sourceMappingURL=search-ranker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-ranker.d.ts","sourceRoot":"","sources":["../../src/search/search-ranker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,cAAc,EACd,cAAc,EAEd,YAAY,EACZ,aAAa,EACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAiB;gBAEpB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;IAO7C;;;;;;;;;;OAUG;IACH,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM;IAc/C;;;OAGG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAI/C;;;OAGG;IACH,uBAAuB,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM;IAIxD;;;OAGG;IACH,uBAAuB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,GAAE,MAAW,GAAG,MAAM;IAa3E;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM;IAiB/C;;OAEG;IACH,WAAW,CAAC,CAAC,EACX,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,EAC1C,UAAU,EAAE,MAAM,EAAE,EACpB,SAAS,EAAE,GAAG,CACZ,MAAM,EACN;QACE,YAAY,EAAE,MAAM,CAAC;QACrB,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC3C,CACF,EACD,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,YAAY,CAAC,CAAC,CAAC,EAAE;IA+CpB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAQ5B;;;;;;;;;;;;OAYG;IACH,aAAa,CACX,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,EAAE,GAAE,MAAY,EAChB,CAAC,GAAE,MAAa,GACf,MAAM;IAYT;;OAEG;IACH,aAAa,CACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,GAAE,MAAiB,EACzB,OAAO,GAAE,MAAkB,EAC3B,SAAS,CAAC,EAAE,SAAS,GACpB,MAAM;IAkBT;;OAEG;IACH,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,GAAE,MAAY,EACvB,MAAM,GAAE,MAAiB,EACzB,OAAO,GAAE,MAAkB,GAC1B,MAAM;IAiDT;;OAEG;IACH,2BAA2B,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM;CAqDnF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,YAAY,CAE5E"}
|