@medusajs/search-postgres 2.19.0-snapshot-20260811095123
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/README.md +131 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations/Migration20260807120000.d.ts +17 -0
- package/dist/migrations/Migration20260807120000.d.ts.map +1 -0
- package/dist/migrations/Migration20260807120000.js +56 -0
- package/dist/migrations/Migration20260807120000.js.map +1 -0
- package/dist/services/postgres-search.d.ts +200 -0
- package/dist/services/postgres-search.d.ts.map +1 -0
- package/dist/services/postgres-search.js +1054 -0
- package/dist/services/postgres-search.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utils/documents.d.ts +19 -0
- package/dist/utils/documents.d.ts.map +1 -0
- package/dist/utils/documents.js +97 -0
- package/dist/utils/documents.js.map +1 -0
- package/dist/utils/extensions.d.ts +50 -0
- package/dist/utils/extensions.d.ts.map +1 -0
- package/dist/utils/extensions.js +129 -0
- package/dist/utils/extensions.js.map +1 -0
- package/dist/utils/facets.d.ts +31 -0
- package/dist/utils/facets.d.ts.map +1 -0
- package/dist/utils/facets.js +198 -0
- package/dist/utils/facets.js.map +1 -0
- package/dist/utils/filters.d.ts +17 -0
- package/dist/utils/filters.d.ts.map +1 -0
- package/dist/utils/filters.js +237 -0
- package/dist/utils/filters.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +22 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/plan.d.ts +86 -0
- package/dist/utils/plan.d.ts.map +1 -0
- package/dist/utils/plan.js +238 -0
- package/dist/utils/plan.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# PostgreSQL search provider
|
|
2
|
+
|
|
3
|
+
Search provider for Medusa backed by PostgreSQL, with two engines:
|
|
4
|
+
|
|
5
|
+
| Engine | When to use | Keyword | Vector |
|
|
6
|
+
| ------------------ | ---------------------------------------- | --------------------------- | -------------------- |
|
|
7
|
+
| `native` (default) | Local / self-hosted / any Postgres | GIN + `ts_rank` + `pg_trgm` | Not supported |
|
|
8
|
+
| `lakebase` | Medusa Cloud / Neon with Lakebase Search | `lakebase_bm25` (BM25) | `lakebase_ann` (ANN) |
|
|
9
|
+
|
|
10
|
+
## Enable it
|
|
11
|
+
|
|
12
|
+
### Native (default, works locally and on Medusa Cloud)
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
modules: [
|
|
16
|
+
{
|
|
17
|
+
resolve: "@medusajs/medusa/search",
|
|
18
|
+
options: {
|
|
19
|
+
providers: [
|
|
20
|
+
{
|
|
21
|
+
resolve: "@medusajs/medusa/search-postgres",
|
|
22
|
+
id: "postgres",
|
|
23
|
+
options: {
|
|
24
|
+
// engine: "native", // default
|
|
25
|
+
// language: "english",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Lakebase (works only on Medusa Cloud)
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
{
|
|
38
|
+
resolve: "@medusajs/medusa/search-postgres",
|
|
39
|
+
id: "postgres",
|
|
40
|
+
options: {
|
|
41
|
+
engine: "lakebase",
|
|
42
|
+
// Optional: embed text for search_options.vector.query
|
|
43
|
+
// embedder: async (text) => { ... return number[] },
|
|
44
|
+
// vector_distance: "cosine", // or "l2" | "inner_product"
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Then:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx medusa db:migrate
|
|
53
|
+
npx medusa db:migrate-search
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The migration always enables `pg_trgm` + `unaccent` and creates the catalog. Lakebase extensions are created at runtime when `engine: "lakebase"` (they need preloaded libraries that migrations alone cannot enable).
|
|
57
|
+
|
|
58
|
+
## Provider options
|
|
59
|
+
|
|
60
|
+
| Option | Default | Description |
|
|
61
|
+
| ----------------- | ----------- | -------------------------------------------------------------------------------------- |
|
|
62
|
+
| `engine` | `"native"` | `"native"` or `"lakebase"` |
|
|
63
|
+
| `language` | `"english"` | Text search config. With `unaccent`, creates `medusa_search_<language>`. |
|
|
64
|
+
| `embedder` | — | `(text) => Promise<number[]>`. Required for `search_options.vector.query` on lakebase. |
|
|
65
|
+
| `vector_distance` | `"cosine"` | ANN metric: `cosine`, `l2`, or `inner_product`. |
|
|
66
|
+
|
|
67
|
+
## Vector fields (lakebase only)
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
defineSearchIndex({
|
|
71
|
+
name: "product",
|
|
72
|
+
entity: "product",
|
|
73
|
+
fields: {
|
|
74
|
+
id: { type: "keyword", filterable: true },
|
|
75
|
+
title: { type: "text", searchable: { weight: 3 } },
|
|
76
|
+
embedding: { type: "vector", dimensions: 1536 },
|
|
77
|
+
},
|
|
78
|
+
// ...
|
|
79
|
+
})
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Documents must include the embedding array on upsert. Query with:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
await query.search({
|
|
86
|
+
entity: "product",
|
|
87
|
+
filters: { q: "red shoes" },
|
|
88
|
+
search_options: {
|
|
89
|
+
vector: {
|
|
90
|
+
field: "embedding",
|
|
91
|
+
value: embeddingArray, // or query: "red shoes" with embedder configured
|
|
92
|
+
semantic_ratio: 0.5, // 0 = keyword, 1 = vector, in between = RRF hybrid
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## What it supports
|
|
99
|
+
|
|
100
|
+
| | native | lakebase |
|
|
101
|
+
| ---------------- | ------------------------------------------------------- | ------------------------ |
|
|
102
|
+
| Free text | `ts_rank` + weights | BM25 via `lakebase_bm25` |
|
|
103
|
+
| Typo tolerance | `pg_trgm` (`word_similarity`) | `pg_trgm` (same) |
|
|
104
|
+
| `match_strategy` | `"all"` (default), `"any"` | same |
|
|
105
|
+
| Filters | `$eq` `$ne` `$in` `$nin` ranges, `$and`/`$or`/`$not`, … | same |
|
|
106
|
+
| Facets | value, range, stats — scoped to the query matches | same |
|
|
107
|
+
| `distinct` | one hit per value, count follows | same |
|
|
108
|
+
| `min_score` | yes, keeps the requested sort | same |
|
|
109
|
+
| Vector / hybrid | — | ANN + RRF |
|
|
110
|
+
| `swapIndex` | yes | yes |
|
|
111
|
+
|
|
112
|
+
Unsupported on both (rejected explicitly): highlighting, geo, cursor pagination, correlated nested predicates, query-time locales, `match_strategy: "last"`.
|
|
113
|
+
|
|
114
|
+
### Filter semantics
|
|
115
|
+
|
|
116
|
+
- Equality and `$in` compile to jsonb containment (`indexed @> …`), which the
|
|
117
|
+
`jsonb_path_ops` GIN index accelerates and which compares numbers and
|
|
118
|
+
booleans natively.
|
|
119
|
+
- On array fields, a bare value or `$eq` means membership — `{ tags: "sale" }`
|
|
120
|
+
matches documents whose `tags` array contains `"sale"`, the same collapse the
|
|
121
|
+
local provider uses.
|
|
122
|
+
- Range operators (`$gt`, …), `$prefix` and `$like` are rejected on array
|
|
123
|
+
fields.
|
|
124
|
+
|
|
125
|
+
### Hybrid queries (lakebase)
|
|
126
|
+
|
|
127
|
+
- Results are rank-fused (RRF), so they can only be ordered by `_score`.
|
|
128
|
+
- `min_score` applies to the fused RRF score (per-arm contributions are at most
|
|
129
|
+
`weight / 61`).
|
|
130
|
+
- `metadata.count` is the exact size of the union of both arms' match sets;
|
|
131
|
+
the fused hit list itself is a bounded candidate window.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAKA,wBAEE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const postgres_search_1 = require("./services/postgres-search");
|
|
5
|
+
const services = [postgres_search_1.PostgresSearchService];
|
|
6
|
+
exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.SEARCH, {
|
|
7
|
+
services,
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qDAAmE;AACnE,gEAAkE;AAElE,MAAM,QAAQ,GAAG,CAAC,uCAAqB,CAAC,CAAA;AAExC,kBAAe,IAAA,sBAAc,EAAC,eAAO,CAAC,MAAM,EAAE;IAC5C,QAAQ;CACT,CAAC,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Migration } from "@medusajs/framework/mikro-orm/migrations";
|
|
2
|
+
/**
|
|
3
|
+
* Enables portable search extensions and creates the catalog table.
|
|
4
|
+
*
|
|
5
|
+
* Always enabled (native engine):
|
|
6
|
+
* - `pg_trgm` — typo tolerance
|
|
7
|
+
* - `unaccent` — accent-insensitive FTS
|
|
8
|
+
*
|
|
9
|
+
* Lakebase extensions (`lakebase_text`, `lakebase_vector`) are **not** installed
|
|
10
|
+
* here — they require Neon preload libraries and are created at runtime when
|
|
11
|
+
* `engine: "lakebase"` is set (Medusa Cloud).
|
|
12
|
+
*/
|
|
13
|
+
export declare class Migration20260807120000 extends Migration {
|
|
14
|
+
up(): Promise<void>;
|
|
15
|
+
down(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=Migration20260807120000.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Migration20260807120000.d.ts","sourceRoot":"","sources":["../../src/migrations/Migration20260807120000.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0CAA0C,CAAA;AAEpE;;;;;;;;;;GAUG;AACH,qBAAa,uBAAwB,SAAQ,SAAS;IACrC,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAoCnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAGrC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Migration20260807120000 = void 0;
|
|
4
|
+
const migrations_1 = require("@medusajs/framework/mikro-orm/migrations");
|
|
5
|
+
/**
|
|
6
|
+
* Enables portable search extensions and creates the catalog table.
|
|
7
|
+
*
|
|
8
|
+
* Always enabled (native engine):
|
|
9
|
+
* - `pg_trgm` — typo tolerance
|
|
10
|
+
* - `unaccent` — accent-insensitive FTS
|
|
11
|
+
*
|
|
12
|
+
* Lakebase extensions (`lakebase_text`, `lakebase_vector`) are **not** installed
|
|
13
|
+
* here — they require Neon preload libraries and are created at runtime when
|
|
14
|
+
* `engine: "lakebase"` is set (Medusa Cloud).
|
|
15
|
+
*/
|
|
16
|
+
class Migration20260807120000 extends migrations_1.Migration {
|
|
17
|
+
async up() {
|
|
18
|
+
// Extension creation needs privileges the app role may not have on managed
|
|
19
|
+
// Postgres. The runtime bootstrap degrades gracefully without them, so the
|
|
20
|
+
// migration must not hard-fail either — it only loses typo tolerance /
|
|
21
|
+
// accent folding.
|
|
22
|
+
this.addSql(`
|
|
23
|
+
DO $$
|
|
24
|
+
BEGIN
|
|
25
|
+
BEGIN
|
|
26
|
+
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
|
27
|
+
EXCEPTION WHEN OTHERS THEN
|
|
28
|
+
RAISE NOTICE 'search-postgres: could not enable pg_trgm (%). Typo tolerance will be unavailable.', SQLERRM;
|
|
29
|
+
END;
|
|
30
|
+
BEGIN
|
|
31
|
+
CREATE EXTENSION IF NOT EXISTS unaccent;
|
|
32
|
+
EXCEPTION WHEN OTHERS THEN
|
|
33
|
+
RAISE NOTICE 'search-postgres: could not enable unaccent (%). Accent folding will be unavailable.', SQLERRM;
|
|
34
|
+
END;
|
|
35
|
+
END
|
|
36
|
+
$$;
|
|
37
|
+
`);
|
|
38
|
+
this.addSql(`
|
|
39
|
+
create table if not exists "search_postgres_index" (
|
|
40
|
+
"name" text not null,
|
|
41
|
+
"table_name" text not null,
|
|
42
|
+
"schema_hash" text not null,
|
|
43
|
+
"plan" jsonb not null,
|
|
44
|
+
"document_count" integer not null default 0,
|
|
45
|
+
"created_at" timestamptz not null default now(),
|
|
46
|
+
"updated_at" timestamptz not null default now(),
|
|
47
|
+
constraint "search_postgres_index_pkey" primary key ("name")
|
|
48
|
+
);
|
|
49
|
+
`);
|
|
50
|
+
}
|
|
51
|
+
async down() {
|
|
52
|
+
this.addSql(`drop table if exists "search_postgres_index" cascade;`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.Migration20260807120000 = Migration20260807120000;
|
|
56
|
+
//# sourceMappingURL=Migration20260807120000.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Migration20260807120000.js","sourceRoot":"","sources":["../../src/migrations/Migration20260807120000.ts"],"names":[],"mappings":";;;AAAA,yEAAoE;AAEpE;;;;;;;;;;GAUG;AACH,MAAa,uBAAwB,SAAQ,sBAAS;IAC3C,KAAK,CAAC,EAAE;QACf,2EAA2E;QAC3E,2EAA2E;QAC3E,uEAAuE;QACvE,kBAAkB;QAClB,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;KAeX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;KAWX,CAAC,CAAA;IACJ,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,MAAM,CAAC,uDAAuD,CAAC,CAAA;IACtE,CAAC;CACF;AAxCD,0DAwCC"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { Logger, SearchTypes } from "@medusajs/framework/types";
|
|
2
|
+
import { AbstractSearchProviderService } from "@medusajs/framework/utils";
|
|
3
|
+
import { ExtensionState, IndexPlan, PostgresSearchEngine, PostgresSearchEmbedder, PostgresSearchProviderOptions, PostgresVectorDistance, SqlFragment } from "../utils";
|
|
4
|
+
type DbManager = {
|
|
5
|
+
execute: (sql: string, params?: unknown[]) => Promise<any[]>;
|
|
6
|
+
transactional?: <T>(cb: (manager: DbManager) => Promise<T>) => Promise<T>;
|
|
7
|
+
};
|
|
8
|
+
type InjectedDependencies = {
|
|
9
|
+
manager: DbManager;
|
|
10
|
+
logger?: Logger;
|
|
11
|
+
};
|
|
12
|
+
type StoredIndex = {
|
|
13
|
+
name: string;
|
|
14
|
+
table_name: string;
|
|
15
|
+
schema_hash: string;
|
|
16
|
+
plan: IndexPlan;
|
|
17
|
+
document_count: number;
|
|
18
|
+
created_at: Date | string;
|
|
19
|
+
updated_at: Date | string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Pieces of a search query that push their own placeholders. Each builder is
|
|
23
|
+
* called once per statement in SQL text order, appending to the shared params
|
|
24
|
+
* array, so hits and count queries stay positionally consistent.
|
|
25
|
+
*/
|
|
26
|
+
type QueryParts = {
|
|
27
|
+
table: string;
|
|
28
|
+
/** SELECT-list relevance expression. */
|
|
29
|
+
rankSql: (params: unknown[]) => string;
|
|
30
|
+
/** WHERE conditions (match predicate + filters). */
|
|
31
|
+
conditionsSql: (params: unknown[]) => string[];
|
|
32
|
+
/** Param-free ORDER BY, valid against the selected columns. */
|
|
33
|
+
orderSql: string;
|
|
34
|
+
/**
|
|
35
|
+
* Parameterized ORDER BY for the un-wrapped hits query only — lets the
|
|
36
|
+
* vector path order by `col <=> ?` directly so the ANN index can serve it.
|
|
37
|
+
*/
|
|
38
|
+
fastOrderSql?: (params: unknown[]) => string;
|
|
39
|
+
minScore?: number;
|
|
40
|
+
/** `indexed#>>...` expression to deduplicate on (one hit per value). */
|
|
41
|
+
distinctExpr?: string;
|
|
42
|
+
count: boolean;
|
|
43
|
+
take: number;
|
|
44
|
+
skip: number;
|
|
45
|
+
/** Runs on the same manager before the hits query (e.g. BM25 set_config). */
|
|
46
|
+
prelude?: (manager: DbManager) => Promise<void>;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* PostgreSQL search provider with two engines:
|
|
50
|
+
*
|
|
51
|
+
* - `native` (default) — portable GIN + `ts_rank` + `pg_trgm`
|
|
52
|
+
* - `lakebase` — Neon Lakebase Search (`lakebase_bm25` + `lakebase_ann`)
|
|
53
|
+
*
|
|
54
|
+
* Medusa Cloud uses `engine: "lakebase"`. Local / self-hosted stick to native.
|
|
55
|
+
*/
|
|
56
|
+
export declare class PostgresSearchService extends AbstractSearchProviderService {
|
|
57
|
+
static identifier: string;
|
|
58
|
+
protected readonly manager_: DbManager;
|
|
59
|
+
protected readonly logger_?: Logger;
|
|
60
|
+
protected readonly language_: string;
|
|
61
|
+
protected readonly engine_: PostgresSearchEngine;
|
|
62
|
+
protected readonly embedder_?: PostgresSearchEmbedder;
|
|
63
|
+
protected readonly vectorDistance_: PostgresVectorDistance;
|
|
64
|
+
protected extensionState_: ExtensionState | null;
|
|
65
|
+
constructor({ manager, logger }: InjectedDependencies, options?: PostgresSearchProviderOptions);
|
|
66
|
+
protected normalizeLanguage(language: string): string;
|
|
67
|
+
protected get tsConfig_(): string;
|
|
68
|
+
protected get isLakebase_(): boolean;
|
|
69
|
+
protected ensureExtensions(manager?: DbManager): Promise<ExtensionState>;
|
|
70
|
+
protected assertTypoToleranceAvailable(state: ExtensionState): void;
|
|
71
|
+
protected serializePlan(plan: IndexPlan): string;
|
|
72
|
+
protected deserializePlan(raw: unknown): IndexPlan;
|
|
73
|
+
protected getCatalog(name: string, manager?: DbManager): Promise<StoredIndex | null>;
|
|
74
|
+
protected createDocumentTable(table: string, plan: IndexPlan, manager: DbManager, extensions: ExtensionState): Promise<void>;
|
|
75
|
+
protected ensureBm25Index(table: string, manager?: DbManager): Promise<void>;
|
|
76
|
+
protected dropBm25Index(table: string, manager?: DbManager): Promise<void>;
|
|
77
|
+
protected dropDocumentTable(table: string, manager: DbManager): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Renaming a table leaves its constraint and index names behind, and a later
|
|
80
|
+
* rebuild of the same shadow name would collide with them (or silently skip
|
|
81
|
+
* `CREATE INDEX IF NOT EXISTS`). Rename every table-derived artifact too.
|
|
82
|
+
*/
|
|
83
|
+
protected renameTableArtifacts(from: string, to: string, plan: IndexPlan, manager: DbManager): Promise<void>;
|
|
84
|
+
protected adjustDocumentCount(name: string, delta: number, manager?: DbManager): Promise<void>;
|
|
85
|
+
protected setDocumentCount(name: string, count: number, manager?: DbManager): Promise<void>;
|
|
86
|
+
protected withTransaction<T>(run: (manager: DbManager) => Promise<T>): Promise<T>;
|
|
87
|
+
upsertIndex({ index, }: {
|
|
88
|
+
index: SearchTypes.ResolvedSearchIndexDefinition;
|
|
89
|
+
}): Promise<SearchTypes.SearchTask>;
|
|
90
|
+
deleteIndex({ index, }: {
|
|
91
|
+
index: string;
|
|
92
|
+
}): Promise<SearchTypes.SearchTask>;
|
|
93
|
+
listIndexes(): Promise<SearchTypes.SearchIndexInfo[]>;
|
|
94
|
+
swapIndex({ alias, index, }: {
|
|
95
|
+
alias: string;
|
|
96
|
+
index: string;
|
|
97
|
+
}): Promise<SearchTypes.SearchTask>;
|
|
98
|
+
protected buildSearchVectorSql(weightedParts: {
|
|
99
|
+
text: string;
|
|
100
|
+
weight: "A" | "B" | "C" | "D";
|
|
101
|
+
}[], params: unknown[]): string;
|
|
102
|
+
upsertDocuments({ index, documents, }: {
|
|
103
|
+
index: string;
|
|
104
|
+
documents: SearchTypes.SearchDocument[];
|
|
105
|
+
}): Promise<SearchTypes.SearchTask>;
|
|
106
|
+
deleteDocuments({ index, filters, }: SearchTypes.SearchDeleteDocumentsInput): Promise<SearchTypes.SearchTask>;
|
|
107
|
+
clearIndex({ index, }: {
|
|
108
|
+
index: string;
|
|
109
|
+
}): Promise<SearchTypes.SearchTask>;
|
|
110
|
+
search(input: SearchTypes.ProviderSearchQuery): Promise<SearchTypes.SearchResult>;
|
|
111
|
+
protected resolveQueryEmbedding(vectorOpts: NonNullable<SearchTypes.SearchOptions["vector"]>, plan: IndexPlan): Promise<number[]>;
|
|
112
|
+
/**
|
|
113
|
+
* The keyword match/rank fragments, shared by the keyword path, the hybrid
|
|
114
|
+
* count and the facet scope so they always describe the same result set.
|
|
115
|
+
* Each fragment pushes its own placeholders when invoked.
|
|
116
|
+
*/
|
|
117
|
+
protected keywordFragments(input: {
|
|
118
|
+
query: SearchTypes.ProviderSearchQuery;
|
|
119
|
+
catalog: StoredIndex;
|
|
120
|
+
extensions: ExtensionState;
|
|
121
|
+
}): {
|
|
122
|
+
q?: string;
|
|
123
|
+
needsBm25Limit: boolean;
|
|
124
|
+
rankSql: (params: unknown[]) => string;
|
|
125
|
+
matchSql?: (params: unknown[]) => string;
|
|
126
|
+
};
|
|
127
|
+
protected searchKeyword(input: {
|
|
128
|
+
input: SearchTypes.ProviderSearchQuery;
|
|
129
|
+
catalog: StoredIndex;
|
|
130
|
+
extensions: ExtensionState;
|
|
131
|
+
skip: number;
|
|
132
|
+
take: number;
|
|
133
|
+
}): Promise<{
|
|
134
|
+
hitRows: any[];
|
|
135
|
+
count: number | null;
|
|
136
|
+
}>;
|
|
137
|
+
protected searchVector(input: {
|
|
138
|
+
input: SearchTypes.ProviderSearchQuery;
|
|
139
|
+
catalog: StoredIndex;
|
|
140
|
+
queryEmbedding: number[];
|
|
141
|
+
skip: number;
|
|
142
|
+
take: number;
|
|
143
|
+
}): Promise<{
|
|
144
|
+
hitRows: any[];
|
|
145
|
+
count: number | null;
|
|
146
|
+
}>;
|
|
147
|
+
protected searchHybrid(input: {
|
|
148
|
+
input: SearchTypes.ProviderSearchQuery;
|
|
149
|
+
catalog: StoredIndex;
|
|
150
|
+
extensions: ExtensionState;
|
|
151
|
+
queryEmbedding: number[];
|
|
152
|
+
semanticRatio: number;
|
|
153
|
+
skip: number;
|
|
154
|
+
take: number;
|
|
155
|
+
}): Promise<{
|
|
156
|
+
hitRows: any[];
|
|
157
|
+
count: number | null;
|
|
158
|
+
}>;
|
|
159
|
+
/**
|
|
160
|
+
* Runs the hits + count statements for a single-arm search. Wraps the base
|
|
161
|
+
* select in subqueries when `min_score` or `distinct` need to see the score
|
|
162
|
+
* as a real column.
|
|
163
|
+
*/
|
|
164
|
+
protected executeQuery(parts: QueryParts): Promise<{
|
|
165
|
+
hitRows: any[];
|
|
166
|
+
count: number | null;
|
|
167
|
+
}>;
|
|
168
|
+
searchMany(inputs: SearchTypes.ProviderSearchQuery[]): Promise<SearchTypes.SearchResult[]>;
|
|
169
|
+
/**
|
|
170
|
+
* The WHERE fragment facets are scoped by: the filters plus the same match
|
|
171
|
+
* predicate as the hits, so facet counts describe the result set.
|
|
172
|
+
*/
|
|
173
|
+
protected buildFacetScope(input: {
|
|
174
|
+
input: SearchTypes.ProviderSearchQuery;
|
|
175
|
+
catalog: StoredIndex;
|
|
176
|
+
extensions: ExtensionState;
|
|
177
|
+
useKeyword: boolean;
|
|
178
|
+
useVector: boolean;
|
|
179
|
+
}): SqlFragment | undefined;
|
|
180
|
+
protected resolveFacets(input: {
|
|
181
|
+
table: string;
|
|
182
|
+
plan: IndexPlan;
|
|
183
|
+
scopeWhere?: SqlFragment;
|
|
184
|
+
requests?: (string | SearchTypes.SearchFacetRequest)[];
|
|
185
|
+
}): Promise<Record<string, SearchTypes.SearchFacetResult> | undefined>;
|
|
186
|
+
protected onTheFlyTextExpr(paths: string[]): string;
|
|
187
|
+
protected onTheFlyVectorExpr(paths: string[], plan: IndexPlan): string;
|
|
188
|
+
protected resolveOrderBy(input: SearchTypes.ProviderSearchQuery, plan: IndexPlan, hasScore: boolean): string;
|
|
189
|
+
/**
|
|
190
|
+
* Validates `search_options.distinct` and returns the SQL expression to
|
|
191
|
+
* deduplicate on, or undefined when not requested.
|
|
192
|
+
*/
|
|
193
|
+
protected resolveDistinct(distinct: string | undefined, plan: IndexPlan, indexName: string): string | undefined;
|
|
194
|
+
/** Reads a dotted path from an `indexed` jsonb value returned by a query. */
|
|
195
|
+
protected readIndexedValue(indexed: unknown, path: string): string | undefined;
|
|
196
|
+
protected retrieve(index: string): Promise<StoredIndex>;
|
|
197
|
+
protected task(index: string): SearchTypes.SearchTask;
|
|
198
|
+
}
|
|
199
|
+
export {};
|
|
200
|
+
//# sourceMappingURL=postgres-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-search.d.ts","sourceRoot":"","sources":["../../src/services/postgres-search.ts"],"names":[],"mappings":"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"}
|