@lde/search-typesense 0.27.4 → 0.29.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.
- package/dist/blue-green-rebuild.d.ts +7 -8
- package/dist/blue-green-rebuild.d.ts.map +1 -1
- package/dist/blue-green-rebuild.js +27 -41
- package/dist/collection-definition.d.ts +17 -12
- package/dist/collection-definition.d.ts.map +1 -1
- package/dist/collection-definition.js +253 -54
- package/dist/documents.d.ts +147 -0
- package/dist/documents.d.ts.map +1 -0
- package/dist/documents.js +529 -0
- package/dist/in-place-rebuild.d.ts +30 -35
- package/dist/in-place-rebuild.d.ts.map +1 -1
- package/dist/in-place-rebuild.js +56 -128
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/lookup.d.ts +16 -7
- package/dist/lookup.d.ts.map +1 -1
- package/dist/lookup.js +49 -7
- package/dist/query-compiler.d.ts.map +1 -1
- package/dist/query-compiler.js +141 -23
- package/dist/rebuild-support.d.ts +1 -41
- package/dist/rebuild-support.d.ts.map +1 -1
- package/dist/rebuild-support.js +3 -76
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +62 -10
- package/package.json +4 -4
- package/dist/import.d.ts +0 -31
- package/dist/import.d.ts.map +0 -1
- package/dist/import.js +0 -60
- package/dist/sweep.d.ts +0 -70
- package/dist/sweep.d.ts.map +0 -1
- package/dist/sweep.js +0 -113
package/dist/query-compiler.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fold } from '@lde/text-normalization';
|
|
2
|
-
import { fieldNamed, filterOperator, filterOperatorFor, ID_FIELD, isoToUnixSeconds, isRangeFacet, pageForOffset, physicalFields, searchableFields, } from '@lde/search/adapter';
|
|
2
|
+
import { fieldNamed, filterOperator, filterOperatorFor, ID_FIELD, isoToUnixSeconds, isInternalField, isRangeFacet, isWelded, joinGraph, localLookupTypeOf, pageForOffset, physicalFields, nestedReferenceType, resolvePath, searchableFields, } from '@lde/search/adapter';
|
|
3
3
|
/**
|
|
4
4
|
* Compile the engine-neutral {@link SearchQuery} into Typesense search
|
|
5
5
|
* parameters – the query half of the engine adapter. Pure (no client, no env),
|
|
@@ -16,7 +16,7 @@ export function buildSearchParams(query, searchType, options = {}) {
|
|
|
16
16
|
const folded = query.text !== undefined && query.text.length > 0
|
|
17
17
|
? fold(query.text)
|
|
18
18
|
: undefined;
|
|
19
|
-
const { names, weights } = queryFields(searchType, query.locale);
|
|
19
|
+
const { names, weights } = queryFields(searchType, query.locale, options.schema);
|
|
20
20
|
const filterBy = compileFilterBy(query.where, searchType, options);
|
|
21
21
|
const sortBy = query.orderBy
|
|
22
22
|
.map((sort) => compileSort(sort, searchType, query.locale))
|
|
@@ -78,16 +78,41 @@ function compileRangeFacet(name, ranges) {
|
|
|
78
78
|
* 1), so a match in the user’s language ranks higher while cross-language matches
|
|
79
79
|
* still surface.
|
|
80
80
|
*/
|
|
81
|
-
function queryFields(searchType, locale) {
|
|
81
|
+
function queryFields(searchType, locale, schema) {
|
|
82
82
|
const names = [];
|
|
83
83
|
const weights = [];
|
|
84
|
+
collectSearchable(searchType, locale, schema, '', new Set(), names, weights);
|
|
85
|
+
return { names, weights };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Collect the searchable physical fields of a type and of everything it nests,
|
|
89
|
+
* each under the path an engine addresses it by.
|
|
90
|
+
*
|
|
91
|
+
* Nested fields are walked because a nested field may declare `searchable`
|
|
92
|
+
* (ADR 24) – and a companion that is indexed but absent from `query_by` is the
|
|
93
|
+
* worst of both: it costs the RAM of an indexed field and matches nothing, in
|
|
94
|
+
* silence. So the walk here is what makes that Role mean anything.
|
|
95
|
+
*
|
|
96
|
+
* `onPath` guards the walk, and is scoped to the PATH rather than to the walk
|
|
97
|
+
* as a whole: two fields may nest one type – `creator` and `contributor` over
|
|
98
|
+
* the same edge – and each reaches it under its own prefix, so each must
|
|
99
|
+
* contribute its own companions. A set shared across the walk would let the
|
|
100
|
+
* first field claim the type and leave the second's companions indexed but
|
|
101
|
+
* unqueried. What it does guard is a type reached from ITSELF, which a
|
|
102
|
+
* {@link ReferenceStrategy.local local} lookup can do.
|
|
103
|
+
*/
|
|
104
|
+
function collectSearchable(searchType, locale, schema, prefix, onPath, names, weights) {
|
|
105
|
+
if (onPath.has(searchType.name)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const walked = new Set(onPath).add(searchType.name);
|
|
84
109
|
for (const field of searchableFields(searchType)) {
|
|
85
110
|
const search = physicalFields(field).search;
|
|
86
111
|
const baseWeight = field.searchable.weight;
|
|
87
112
|
if (field.kind === 'text') {
|
|
88
113
|
const locales = field.locales;
|
|
89
114
|
search.forEach((name, index) => {
|
|
90
|
-
names.push(name);
|
|
115
|
+
names.push(qualify(prefix, name));
|
|
91
116
|
// The active locale keeps full weight; `und` is language-neutral, so
|
|
92
117
|
// it is never demoted (an untagged-only field would otherwise always
|
|
93
118
|
// rank below its declared weight).
|
|
@@ -98,12 +123,26 @@ function queryFields(searchType, locale) {
|
|
|
98
123
|
}
|
|
99
124
|
else {
|
|
100
125
|
for (const name of search) {
|
|
101
|
-
names.push(name);
|
|
126
|
+
names.push(qualify(prefix, name));
|
|
102
127
|
weights.push(baseWeight);
|
|
103
128
|
}
|
|
104
129
|
}
|
|
105
130
|
}
|
|
106
|
-
|
|
131
|
+
if (schema === undefined) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
for (const field of searchType.fields) {
|
|
135
|
+
// An internal field is pruned before the writer and declared in no
|
|
136
|
+
// collection, so its target's companions exist nowhere – asking `query_by`
|
|
137
|
+
// for one makes the ENGINE reject every search on the collection.
|
|
138
|
+
if (isInternalField(field)) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const nested = nestedReferenceType(schema, field) ?? localLookupTypeOf(field, schema);
|
|
142
|
+
if (nested !== undefined) {
|
|
143
|
+
collectSearchable(nested, locale, schema, qualify(prefix, field.name), walked, names, weights);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
107
146
|
}
|
|
108
147
|
/** AND-join the compiled `where` clauses. A clause that states no constraint is
|
|
109
148
|
* skipped; one that can match nothing compiles to {@link MATCHES_NOTHING}
|
|
@@ -201,16 +240,31 @@ const UNUSABLE = Symbol('unusable');
|
|
|
201
240
|
function compileCriterion(criterion, searchType, options) {
|
|
202
241
|
const on = criterion.on ?? [];
|
|
203
242
|
if (on.length === 0) {
|
|
204
|
-
return
|
|
243
|
+
return isWelded(criterion)
|
|
244
|
+
? compileWelded(criterion, searchType, options.schema, '')
|
|
245
|
+
: compileLeaf(criterion, searchType, options.schema);
|
|
205
246
|
}
|
|
247
|
+
// The path carries two kinds of hop, and they compile differently: a JOIN
|
|
248
|
+
// crosses into another collection and wraps the leaf in `$collection(…)`; a
|
|
249
|
+
// NESTING stays in this document and qualifies the leaf’s field name. The
|
|
250
|
+
// schema is what tells them apart, so without one every hop is read as a
|
|
251
|
+
// join – exactly the behaviour before nesting existed.
|
|
252
|
+
const resolvedPath = options.schema === undefined
|
|
253
|
+
? undefined
|
|
254
|
+
: resolvePath(searchType, on, options.schema, joinGraph(options.schema));
|
|
255
|
+
if (typeof resolvedPath === 'string') {
|
|
256
|
+
return UNUSABLE;
|
|
257
|
+
}
|
|
258
|
+
const joinHops = resolvedPath?.joinPath ?? on;
|
|
259
|
+
const nestedHops = resolvedPath?.nestedPath ?? [];
|
|
206
260
|
// A joined criterion constrains a document in ANOTHER collection, so the leaf
|
|
207
261
|
// is compiled against the type that path reaches and then wrapped, one
|
|
208
262
|
// `$collection(…)` per hop, outermost hop first:
|
|
209
263
|
// `['dataset', 'publisher']` → `$datasets($publishers(id:=…))`.
|
|
210
264
|
const collections = [];
|
|
211
265
|
let target = searchType;
|
|
212
|
-
for (let hop = 1; hop <=
|
|
213
|
-
const resolved = options.joinTargetFor?.(searchType,
|
|
266
|
+
for (let hop = 1; hop <= joinHops.length; hop++) {
|
|
267
|
+
const resolved = options.joinTargetFor?.(searchType, joinHops.slice(0, hop));
|
|
214
268
|
if (resolved === undefined) {
|
|
215
269
|
// An unresolvable path is a criterion that cannot be compiled at all –
|
|
216
270
|
// false, so it drops out and its siblings still stand. Through the
|
|
@@ -220,7 +274,11 @@ function compileCriterion(criterion, searchType, options) {
|
|
|
220
274
|
collections.push(resolved.collection);
|
|
221
275
|
target = resolved.searchType;
|
|
222
276
|
}
|
|
223
|
-
const
|
|
277
|
+
const leafType = resolvedPath?.leafType ?? target;
|
|
278
|
+
const prefix = nestedHops.join('.');
|
|
279
|
+
const leaf = isWelded(criterion)
|
|
280
|
+
? compileWelded(criterion, leafType, options.schema, prefix)
|
|
281
|
+
: compileLeaf(criterion, leafType, options.schema, prefix);
|
|
224
282
|
// A vacuous leaf states no constraint on the referent, so the join as a whole
|
|
225
283
|
// states none either – the reading, and so the outcome, passes straight
|
|
226
284
|
// through the hops.
|
|
@@ -229,9 +287,16 @@ function compileCriterion(criterion, searchType, options) {
|
|
|
229
287
|
}
|
|
230
288
|
return collections.reduceRight((inner, collection) => `$${collection}(${inner})`, leaf);
|
|
231
289
|
}
|
|
232
|
-
/**
|
|
233
|
-
*
|
|
234
|
-
|
|
290
|
+
/**
|
|
291
|
+
* The criterion’s own term, against the type it actually constrains – the
|
|
292
|
+
* searched type, the one its join path reaches, or the reference type its
|
|
293
|
+
* nesting path walks into.
|
|
294
|
+
*
|
|
295
|
+
* `prefix` is that nesting path, dotted: an engine addresses a stored nested
|
|
296
|
+
* document by qualifying the field name, so `role` inside `creator` becomes
|
|
297
|
+
* `creator.role`. Empty for every unnested criterion.
|
|
298
|
+
*/
|
|
299
|
+
function compileLeaf(criterion, searchType, schema, prefix = '') {
|
|
235
300
|
// `id` is the Typesense document key, not a declared field. Exact `:=`
|
|
236
301
|
// membership, like a non-facet field ({@link compileMembership}), so an IRI
|
|
237
302
|
// cannot partial-match on a shared path segment. (`fetchLabels` resolves
|
|
@@ -239,7 +304,12 @@ function compileLeaf(criterion, searchType, schema) {
|
|
|
239
304
|
// clause.) An empty identity membership enumerates NO document, so it is
|
|
240
305
|
// unusable rather than vacuous – the one place the two readings diverge.
|
|
241
306
|
if (criterion.field === ID_FIELD) {
|
|
242
|
-
|
|
307
|
+
// `id` names the DOCUMENT key, which exists only at the top level: inside a
|
|
308
|
+
// nested reference there is no document to key. Compiling it under a prefix
|
|
309
|
+
// would filter the root collection's `id` instead – a different question,
|
|
310
|
+
// silently answered. `assertValidQuery` rejects it first; this is the guard
|
|
311
|
+
// for a hand-built query.
|
|
312
|
+
return prefix === '' && 'in' in criterion && criterion.in.length > 0
|
|
243
313
|
? `${ID_FIELD}:=[${criterion.in.map(escapeFilterValue).join(',')}]`
|
|
244
314
|
: UNUSABLE;
|
|
245
315
|
}
|
|
@@ -254,13 +324,57 @@ function compileLeaf(criterion, searchType, schema) {
|
|
|
254
324
|
}
|
|
255
325
|
if ('in' in criterion) {
|
|
256
326
|
return criterion.in.length > 0
|
|
257
|
-
? compileMembership(field, criterion.in, schema)
|
|
327
|
+
? compileMembership(field, criterion.in, schema, prefix)
|
|
258
328
|
: VACUOUS;
|
|
259
329
|
}
|
|
260
330
|
if ('range' in criterion) {
|
|
261
|
-
return compileRange(field, criterion.range) ?? VACUOUS;
|
|
331
|
+
return compileRange(field, criterion.range, prefix) ?? VACUOUS;
|
|
332
|
+
}
|
|
333
|
+
// Every other shape returned above; a welded criterion never reaches here
|
|
334
|
+
// (compileWelded handles it before the leaf compiler is called).
|
|
335
|
+
return `${qualify(prefix, field.name)}:=${criterion.is}`;
|
|
336
|
+
}
|
|
337
|
+
/** A field name under its nesting path, if any – the one place the dotted
|
|
338
|
+
* addressing an engine uses for a stored nested document is spelled. */
|
|
339
|
+
function qualify(prefix, name) {
|
|
340
|
+
return prefix === '' ? name : `${prefix}.${name}`;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* A **welded** criterion: `path.{a && b}`, matching a document with ONE entry
|
|
344
|
+
* that satisfies every condition – as against `path.a && path.b`, which two
|
|
345
|
+
* different entries can satisfy between them.
|
|
346
|
+
*
|
|
347
|
+
* Each condition is compiled against the reference type with an EMPTY prefix,
|
|
348
|
+
* so what goes inside the braces is always a leaf name. That is a correctness
|
|
349
|
+
* requirement, not tidiness: Typesense 30.2 **hangs** on a dotted path inside a
|
|
350
|
+
* group (`creator.{creator.name:=…}` never returns – no error, no result), so
|
|
351
|
+
* the compiler must be structurally incapable of emitting one. A field whose
|
|
352
|
+
* value is itself nested is reached through its identity companion, which is a
|
|
353
|
+
* leaf ({@link physicalFields}).
|
|
354
|
+
*
|
|
355
|
+
* A condition that states no constraint drops out, and the weld is whatever
|
|
356
|
+
* remains; a weld left with nothing is vacuous like any other empty clause.
|
|
357
|
+
*/
|
|
358
|
+
function compileWelded(criterion, searchType, schema, prefix) {
|
|
359
|
+
const entryType = schema &&
|
|
360
|
+
nestedReferenceType(schema, fieldNamed(searchType, criterion.field) ?? {});
|
|
361
|
+
if (entryType === undefined) {
|
|
362
|
+
return UNUSABLE;
|
|
363
|
+
}
|
|
364
|
+
const conditions = [];
|
|
365
|
+
for (const condition of criterion.entry) {
|
|
366
|
+
const compiled = compileLeaf(condition, entryType, schema);
|
|
367
|
+
if (compiled === UNUSABLE) {
|
|
368
|
+
return UNUSABLE;
|
|
369
|
+
}
|
|
370
|
+
if (compiled !== VACUOUS) {
|
|
371
|
+
conditions.push(compiled);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (conditions.length === 0) {
|
|
375
|
+
return VACUOUS;
|
|
262
376
|
}
|
|
263
|
-
return `${field.
|
|
377
|
+
return `${qualify(prefix, criterion.field)}.{${conditions.join(' && ')}}`;
|
|
264
378
|
}
|
|
265
379
|
/**
|
|
266
380
|
* A membership clause. A non-facet (tokenized) field uses the exact `:=`
|
|
@@ -272,11 +386,15 @@ function compileLeaf(criterion, searchType, schema) {
|
|
|
272
386
|
* filter on such a field is exactly what the policy promises stays whole, so
|
|
273
387
|
* it must compile exact, not tokenized.
|
|
274
388
|
*/
|
|
275
|
-
function compileMembership(field, values, schema) {
|
|
389
|
+
function compileMembership(field, values, schema, prefix = '') {
|
|
276
390
|
const list = `[${values.map(escapeFilterValue).join(',')}]`;
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
391
|
+
const names = physicalFields(field, schema);
|
|
392
|
+
// An inline reference stores a nested object, which an engine cannot filter.
|
|
393
|
+
// Its identity companion is the flat id field standing in for it – so the
|
|
394
|
+
// logical name a consumer writes and the physical name the engine reads
|
|
395
|
+
// differ here, and only here.
|
|
396
|
+
const name = qualify(prefix, names.identity ?? field.name);
|
|
397
|
+
return names.facet === name ? `${name}:${list}` : `${name}:=${list}`;
|
|
280
398
|
}
|
|
281
399
|
/** An inclusive Typesense range clause, or `undefined` when neither bound is
|
|
282
400
|
* usable. Which of the two readings that is – the caller set no bounds, or the
|
|
@@ -285,8 +403,8 @@ function compileMembership(field, values, schema) {
|
|
|
285
403
|
* from the conjunction widens it, so the same reading cannot be right in both
|
|
286
404
|
* positions. `validateQuery` rejects an unreadable bound outright instead,
|
|
287
405
|
* which is the only answer that neither widens nor narrows. */
|
|
288
|
-
function compileRange(field, range) {
|
|
289
|
-
const name = field.name;
|
|
406
|
+
function compileRange(field, range, prefix = '') {
|
|
407
|
+
const name = qualify(prefix, field.name);
|
|
290
408
|
// A bound a caller sent as `null` – a GraphQL variable left unfilled, which
|
|
291
409
|
// the surface passes through – is a bound NOT SET, not a bound of `null`.
|
|
292
410
|
// Read literally it reaches the engine as `datePosted:[null..…]`, which
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { SearchSchema, SearchType } from '@lde/search';
|
|
1
|
+
import type { SearchType } from '@lde/search';
|
|
3
2
|
import { type CollectionDefinitionOptions } from './collection-definition.js';
|
|
4
3
|
/**
|
|
5
4
|
* The tuning knobs both rebuild writers share, on top of the collection-definition
|
|
@@ -39,43 +38,4 @@ export interface ResolvedRebuildOptions {
|
|
|
39
38
|
* been paid for.
|
|
40
39
|
*/
|
|
41
40
|
export declare function resolveRebuildOptions(searchType: SearchType, options: RebuildOptions): ResolvedRebuildOptions;
|
|
42
|
-
/**
|
|
43
|
-
* Reject a {@link SearchType} that declares any of the bookkeeping field names
|
|
44
|
-
* a writer stamps, so a domain field can never collide with `source` /
|
|
45
|
-
* `last_seen`.
|
|
46
|
-
*/
|
|
47
|
-
export declare function assertNoReservedFields(searchType: SearchType, reserved: readonly string[]): void;
|
|
48
|
-
/**
|
|
49
|
-
* Reject a declared dataset field the provenance bookkeeping cannot be kept on.
|
|
50
|
-
* A type declaring one makes it the collection’s provenance field – the column
|
|
51
|
-
* the membership sweep enumerates and deletes by – so the declaration has to answer
|
|
52
|
-
* *which single dataset is this document’s* the way the private `source` field
|
|
53
|
-
* did:
|
|
54
|
-
*
|
|
55
|
-
* - **not `array`**: Typesense reads `field:=[a,b]` over a `string[]` as
|
|
56
|
-
* *contains any*, so a departed source would take every document that merely
|
|
57
|
-
* mentions it – including entities another selected dataset still
|
|
58
|
-
* contributes;
|
|
59
|
-
* - **no `transform`**: the sweep compares the stored value against the run’s
|
|
60
|
-
* selection, which carries raw dataset IRIs, so a transformed value would
|
|
61
|
-
* match nothing and the sweep would silently stop deleting;
|
|
62
|
-
* - **`facetable`** where the writer enumerates the indexed sources by faceting
|
|
63
|
-
* it (the In-place writer does; Blue/green only ever filters by a known IRI)
|
|
64
|
-
* – and faceted **on its own name**: a reference inheriting a facet policy
|
|
65
|
-
* from the type it names facets a companion holding only the admitted keys
|
|
66
|
-
* (`physicalFields(field, schema).facet`), so enumerating the sources
|
|
67
|
-
* through it would miss every dataset the policy excludes. `schema` is what
|
|
68
|
-
* resolves that; without one no policy is visible, as nowhere else.
|
|
69
|
-
*
|
|
70
|
-
* Thrown at writer construction, so a declaration that cannot be swept fails
|
|
71
|
-
* before a run touches the index rather than at the sweep, after the writes.
|
|
72
|
-
*/
|
|
73
|
-
export declare function assertSweepableProvenanceField(searchType: SearchType, options: {
|
|
74
|
-
readonly requireFacetable: boolean;
|
|
75
|
-
readonly schema?: SearchSchema;
|
|
76
|
-
}): void;
|
|
77
|
-
/** Stamp each document with fixed bookkeeping fields as it streams past. */
|
|
78
|
-
export declare function stampDocuments<TDocument>(documents: AsyncIterable<TDocument>, stamp: Readonly<Record<string, string>>): AsyncIterable<TDocument & Record<string, string>>;
|
|
79
|
-
/** Delete a collection’s documents matching a Typesense filter. */
|
|
80
|
-
export declare function deleteByFilter(client: Client, collection: string, filterBy: string): Promise<void>;
|
|
81
41
|
//# sourceMappingURL=rebuild-support.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rebuild-support.d.ts","sourceRoot":"","sources":["../src/rebuild-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"rebuild-support.d.ts","sourceRoot":"","sources":["../src/rebuild-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,4BAA4B,CAAC;AAOpC;;;GAGG;AACH,MAAM,WAAW,cAAe,SAAQ,2BAA2B;IACjE,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;0FAC0F;AAC1F,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;uEAGmE;IACnE,QAAQ,CAAC,iBAAiB,EAAE,2BAA2B,GAAG;QACxD,QAAQ,CAAC,iBAAiB,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,MAAM,CAAC;KAChE,CAAC;CACH;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,cAAc,GACtB,sBAAsB,CAkBxB"}
|
package/dist/rebuild-support.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { joinGraph, referenceFields } from '@lde/search/adapter';
|
|
2
2
|
import { buildCollectionDefinition, } from './collection-definition.js';
|
|
3
3
|
import { deriveCollectionName } from './collection-name.js';
|
|
4
4
|
import { DEFAULT_LOCK_TTL_MS } from './lock.js';
|
|
5
|
-
|
|
5
|
+
/** Documents imported per Typesense request unless a writer is told otherwise. */
|
|
6
|
+
const DEFAULT_BATCH_SIZE = 1000;
|
|
6
7
|
/**
|
|
7
8
|
* Apply the shared defaults, once, so neither writer restates them – including
|
|
8
9
|
* the collection naming, derived from each type ({@link deriveCollectionName})
|
|
@@ -59,77 +60,3 @@ function assertDistinctJoinTargetNames(searchType, options) {
|
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Reject a {@link SearchType} that declares any of the bookkeeping field names
|
|
64
|
-
* a writer stamps, so a domain field can never collide with `source` /
|
|
65
|
-
* `last_seen`.
|
|
66
|
-
*/
|
|
67
|
-
export function assertNoReservedFields(searchType, reserved) {
|
|
68
|
-
const clashing = searchType.fields.filter((field) => reserved.includes(field.name));
|
|
69
|
-
if (clashing.length > 0) {
|
|
70
|
-
throw new Error(`SearchType “${searchType.name}” declares reserved bookkeeping field(s) ${clashing
|
|
71
|
-
.map((field) => `“${field.name}”`)
|
|
72
|
-
.join(', ')}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Reject a declared dataset field the provenance bookkeeping cannot be kept on.
|
|
77
|
-
* A type declaring one makes it the collection’s provenance field – the column
|
|
78
|
-
* the membership sweep enumerates and deletes by – so the declaration has to answer
|
|
79
|
-
* *which single dataset is this document’s* the way the private `source` field
|
|
80
|
-
* did:
|
|
81
|
-
*
|
|
82
|
-
* - **not `array`**: Typesense reads `field:=[a,b]` over a `string[]` as
|
|
83
|
-
* *contains any*, so a departed source would take every document that merely
|
|
84
|
-
* mentions it – including entities another selected dataset still
|
|
85
|
-
* contributes;
|
|
86
|
-
* - **no `transform`**: the sweep compares the stored value against the run’s
|
|
87
|
-
* selection, which carries raw dataset IRIs, so a transformed value would
|
|
88
|
-
* match nothing and the sweep would silently stop deleting;
|
|
89
|
-
* - **`facetable`** where the writer enumerates the indexed sources by faceting
|
|
90
|
-
* it (the In-place writer does; Blue/green only ever filters by a known IRI)
|
|
91
|
-
* – and faceted **on its own name**: a reference inheriting a facet policy
|
|
92
|
-
* from the type it names facets a companion holding only the admitted keys
|
|
93
|
-
* (`physicalFields(field, schema).facet`), so enumerating the sources
|
|
94
|
-
* through it would miss every dataset the policy excludes. `schema` is what
|
|
95
|
-
* resolves that; without one no policy is visible, as nowhere else.
|
|
96
|
-
*
|
|
97
|
-
* Thrown at writer construction, so a declaration that cannot be swept fails
|
|
98
|
-
* before a run touches the index rather than at the sweep, after the writes.
|
|
99
|
-
*/
|
|
100
|
-
export function assertSweepableProvenanceField(searchType, options) {
|
|
101
|
-
const field = datasetField(searchType);
|
|
102
|
-
if (field === undefined || isInternalField(field)) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
const problems = [];
|
|
106
|
-
if (field.array === true) {
|
|
107
|
-
problems.push('it is an array, and a membership sweep over one would delete every document merely mentioning a departed dataset');
|
|
108
|
-
}
|
|
109
|
-
if (field.transform !== undefined) {
|
|
110
|
-
problems.push('it declares a transform, and the sweep matches the stored value against the run’s raw dataset IRIs');
|
|
111
|
-
}
|
|
112
|
-
if (options.requireFacetable && field.facetable !== true) {
|
|
113
|
-
problems.push('it is not facetable, and the membership sweep enumerates the indexed datasets by faceting it');
|
|
114
|
-
}
|
|
115
|
-
else if (options.requireFacetable &&
|
|
116
|
-
physicalFields(field, options.schema).facet !== field.name) {
|
|
117
|
-
problems.push('it inherits a facet policy from the type it names, so the engine facets only the datasets the policy admits, and the membership sweep enumerates the indexed datasets by faceting it');
|
|
118
|
-
}
|
|
119
|
-
if (problems.length > 0) {
|
|
120
|
-
throw new Error(`SearchType “${searchType.name}” declares “${field.name}” over the indexed dataset, which this writer keeps its provenance bookkeeping on, but ${problems.join('; and ')}.`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/** Stamp each document with fixed bookkeeping fields as it streams past. */
|
|
124
|
-
export async function* stampDocuments(documents, stamp) {
|
|
125
|
-
for await (const document of documents) {
|
|
126
|
-
yield { ...document, ...stamp };
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
/** Delete a collection’s documents matching a Typesense filter. */
|
|
130
|
-
export async function deleteByFilter(client, collection, filterBy) {
|
|
131
|
-
await client
|
|
132
|
-
.collections(collection)
|
|
133
|
-
.documents()
|
|
134
|
-
.delete({ filter_by: filterBy });
|
|
135
|
-
}
|
package/dist/search.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAGL,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
|
package/dist/search.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertTypeInSchema, assertValidQuery, displayLangOf, facetableFields, fieldNamed, isInlineReference, isRangeFacet, isUnsatisfiable, joinGraph, labelFieldOf, labelSourceNameOf, nestedReferenceType, outputFields, physicalFields, referenceFields, } from '@lde/search/adapter';
|
|
1
|
+
import { assertTypeInSchema, assertValidQuery, displayLangOf, facetableFields, fieldNamed, isInlineReference, isRangeFacet, isUnsatisfiable, joinGraph, labelFieldOf, labelSourceNameOf, labelTargetNameOf, localLookupTypeOf, nestedReferenceType, outputFields, physicalFields, referenceFields, } from '@lde/search/adapter';
|
|
2
2
|
import { buildSearchParams, escapeFilterValue, } from './query-compiler.js';
|
|
3
3
|
import { deriveCollectionName } from './collection-name.js';
|
|
4
4
|
import { resolveProjection } from './lookup.js';
|
|
@@ -68,9 +68,12 @@ export function createTypesenseSearchEngine(client, schema, options = {}) {
|
|
|
68
68
|
const labelSources = new Map([...schema.values()].map((searchType) => [
|
|
69
69
|
searchType.class,
|
|
70
70
|
new Map(referenceFields(searchType)
|
|
71
|
-
|
|
71
|
+
// An INLINE reference names its label target one level in, through
|
|
72
|
+
// its identity companion: the companion holds that field's ids, so
|
|
73
|
+
// that field's target is what can label them.
|
|
74
|
+
.filter((field) => labelTargetNameOf(field, schema) !== undefined)
|
|
72
75
|
.map((field) => {
|
|
73
|
-
const source = typesByName.get(
|
|
76
|
+
const source = typesByName.get(labelTargetNameOf(field, schema));
|
|
74
77
|
const labelField = labelFieldOf(source);
|
|
75
78
|
return [
|
|
76
79
|
field.name,
|
|
@@ -114,7 +117,18 @@ export function createTypesenseSearchEngine(client, schema, options = {}) {
|
|
|
114
117
|
return [
|
|
115
118
|
searchType.class,
|
|
116
119
|
referenceFields(searchType)
|
|
117
|
-
.filter((field) => field.output === true &&
|
|
120
|
+
.filter((field) => field.output === true &&
|
|
121
|
+
sources?.has(field.name) === true &&
|
|
122
|
+
// A field storing NESTED DOCUMENTS is excluded, and must be: this
|
|
123
|
+
// list drives the per-hit label lookup, which reads each stored
|
|
124
|
+
// value as an id. An inline reference and a `local` lookup store
|
|
125
|
+
// objects, so every entry would contribute the string
|
|
126
|
+
// `"[object Object]"` to the batched `id:[…]` filter. Neither
|
|
127
|
+
// needs entry labels anyway – the referent's own fields are in
|
|
128
|
+
// the entry – and their FACET buckets are labelled by a separate
|
|
129
|
+
// path that reads the companion.
|
|
130
|
+
nestedReferenceType(schema, field) === undefined &&
|
|
131
|
+
localLookupTypeOf(field, schema) === undefined)
|
|
118
132
|
.map((field) => ({
|
|
119
133
|
name: field.name,
|
|
120
134
|
source: sources.get(field.name),
|
|
@@ -538,7 +552,7 @@ export function parseSearchResponse(response, searchType, labels, schema, refere
|
|
|
538
552
|
// reference facet stays id-only even when a cached full-collection map holds
|
|
539
553
|
// its IRIs.
|
|
540
554
|
const referenceFacets = new Set(referenceFields(searchType)
|
|
541
|
-
.filter((field) =>
|
|
555
|
+
.filter((field) => labelTargetNameOf(field, schema) !== undefined)
|
|
542
556
|
.map((field) => field.name));
|
|
543
557
|
const facets = {};
|
|
544
558
|
for (const facet of response.facet_counts ?? []) {
|
|
@@ -587,15 +601,25 @@ function logicalValue(flat, field, labels, schema, referents) {
|
|
|
587
601
|
// reconstructs as a nested Search Document rather than as an IRI plus a
|
|
588
602
|
// label. Nesting is rebuilt HERE, below every surface, so a second
|
|
589
603
|
// surface inherits it instead of reimplementing it (ADR 11).
|
|
604
|
+
const resolved = referents?.get(field.name);
|
|
590
605
|
const nested = nestedReferenceType(schema, field);
|
|
591
606
|
if (nested !== undefined) {
|
|
592
|
-
|
|
607
|
+
// A nested level resolves nothing itself; what it carries are the
|
|
608
|
+
// levels below it, which the entries are reconstructed against.
|
|
609
|
+
return nestedValue(flat[field.name], field, nested, labels, schema, resolved?.children);
|
|
610
|
+
}
|
|
611
|
+
// Checked BEFORE the plain lookup below, because a `local` lookup
|
|
612
|
+
// resolves through the same kind of level while storing a different
|
|
613
|
+
// shape: its stored value is the endpoint's own document, not an id, so
|
|
614
|
+
// reading it as one would stringify the object into a bogus `id`.
|
|
615
|
+
const localType = localLookupTypeOf(field, schema);
|
|
616
|
+
if (localType !== undefined) {
|
|
617
|
+
return localLookupValue(flat[field.name], field, localType, resolved, labels, schema);
|
|
593
618
|
}
|
|
594
619
|
// A resolved lookup carries the referent's own fields, fetched from the
|
|
595
620
|
// target's collection. It reconstructs through the SAME path a hit does,
|
|
596
621
|
// so a consumer cannot tell a projected referent from an inline one.
|
|
597
|
-
|
|
598
|
-
if (resolved !== undefined) {
|
|
622
|
+
if (resolved !== undefined && resolved.via === 'lookup') {
|
|
599
623
|
return lookupValue(flat[field.name], field, resolved, labels, schema);
|
|
600
624
|
}
|
|
601
625
|
// A surfaced inline reference stores nested documents, not IRIs, so a
|
|
@@ -655,10 +679,10 @@ function localizedValue(flat, field) {
|
|
|
655
679
|
* a nested document is read, not addressed. A nested reference type may itself
|
|
656
680
|
* surface an inline reference, which recurses through {@link reconstructDocument}.
|
|
657
681
|
*/
|
|
658
|
-
function nestedValue(raw, field, referenceType, labels, schema) {
|
|
682
|
+
function nestedValue(raw, field, referenceType, labels, schema, children) {
|
|
659
683
|
const referents = (Array.isArray(raw) ? raw : [raw]).filter((referent) => typeof referent === 'object' && referent !== null);
|
|
660
684
|
const documents = referents.map((referent) => {
|
|
661
|
-
const document = reconstructDocument(referent, referenceType, labels, schema);
|
|
685
|
+
const document = reconstructDocument(referent, referenceType, labels, schema, children);
|
|
662
686
|
return typeof referent.id === 'string'
|
|
663
687
|
? { id: referent.id, ...document }
|
|
664
688
|
: document;
|
|
@@ -668,6 +692,34 @@ function nestedValue(raw, field, referenceType, labels, schema) {
|
|
|
668
692
|
}
|
|
669
693
|
return field.array === true ? documents : documents[0];
|
|
670
694
|
}
|
|
695
|
+
/**
|
|
696
|
+
* Rebuild a {@link ReferenceStrategy.local local} lookup: the endpoint’s own
|
|
697
|
+
* document as this document stated it, with the **resolved** document overlaid
|
|
698
|
+
* where the lookup found one.
|
|
699
|
+
*
|
|
700
|
+
* Both sides are the target type’s flat physical shape, so the merge is a plain
|
|
701
|
+
* override and the authoritative value wins field by field. Three cases fall
|
|
702
|
+
* out of one expression, which is the point of storing local fields
|
|
703
|
+
* unconditionally:
|
|
704
|
+
*
|
|
705
|
+
* - identified and indexed → the target’s own record, over what was stated here;
|
|
706
|
+
* - identified but not indexed → what was stated here, plus the `id`, rather
|
|
707
|
+
* than a bare IRI;
|
|
708
|
+
* - not identified → what was stated here, with no `id` at all.
|
|
709
|
+
*/
|
|
710
|
+
function localLookupValue(raw, field, target, resolved, labels, schema) {
|
|
711
|
+
const fetched = resolved?.via === 'lookup' ? resolved.documents : new Map();
|
|
712
|
+
const merged = (Array.isArray(raw) ? raw : [raw])
|
|
713
|
+
.filter((entry) => typeof entry === 'object' && entry !== null)
|
|
714
|
+
.map((entry) => {
|
|
715
|
+
const id = typeof entry.id === 'string' ? entry.id : undefined;
|
|
716
|
+
const authoritative = id === undefined ? undefined : fetched.get(id);
|
|
717
|
+
return authoritative === undefined
|
|
718
|
+
? entry
|
|
719
|
+
: { ...entry, ...authoritative };
|
|
720
|
+
});
|
|
721
|
+
return nestedValue(merged, field, target, labels, schema, resolved?.children);
|
|
722
|
+
}
|
|
671
723
|
/**
|
|
672
724
|
* Rebuild a resolved `lookup` reference: each stored IRI becomes the referent’s
|
|
673
725
|
* own document, read through the **target’s** declaration and carrying whatever
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lde/search-typesense",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"description": "Typesense implementation of the @lde/search SearchEngine port: collection-schema builder, query compiler, label-resolving result reconstruction, and blue/green index lifecycle. Engine-specific (Typesense) but domain-agnostic.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "git+https://github.com/ldelements/lde.git",
|
|
@@ -25,17 +25,17 @@
|
|
|
25
25
|
"!**/*.tsbuildinfo"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@lde/search": "^0.
|
|
28
|
+
"@lde/search": "^0.24.0",
|
|
29
29
|
"@lde/text-normalization": "^0.1.2",
|
|
30
30
|
"tslib": "^2.3.0",
|
|
31
31
|
"typesense": "^3.0.6"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"n3": "^2.
|
|
34
|
+
"n3": "^2.4.0",
|
|
35
35
|
"testcontainers": "^12.1.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@lde/dataset": "^0.7.9",
|
|
39
|
-
"@lde/pipeline": "^0.36.
|
|
39
|
+
"@lde/pipeline": "^0.36.4"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/dist/import.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { Client } from 'typesense';
|
|
2
|
-
/** Documents imported per Typesense request unless a writer is told otherwise. */
|
|
3
|
-
export declare const DEFAULT_BATCH_SIZE = 1000;
|
|
4
|
-
/**
|
|
5
|
-
* Accumulates documents across writes and upserts them into a collection in
|
|
6
|
-
* fixed-size batches, so many small writes (one dataset at a time) still land
|
|
7
|
-
* as few Typesense requests. Call {@link flush} to import the remainder.
|
|
8
|
-
*/
|
|
9
|
-
export declare class BatchImporter<TDocument extends {
|
|
10
|
-
id: string;
|
|
11
|
-
}> {
|
|
12
|
-
private readonly client;
|
|
13
|
-
private readonly collection;
|
|
14
|
-
private readonly batchSize;
|
|
15
|
-
private buffer;
|
|
16
|
-
constructor(client: Client, collection: string, batchSize: number);
|
|
17
|
-
/** Add a stream of documents, importing a batch whenever one fills up. */
|
|
18
|
-
add(documents: AsyncIterable<TDocument>): Promise<void>;
|
|
19
|
-
/** Import any remaining documents. */
|
|
20
|
-
flush(): Promise<void>;
|
|
21
|
-
private importBuffer;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Create-or-replace one batch of whole documents, keyed on `id`, throwing if any
|
|
25
|
-
* individual document fails (Typesense’s bulk import otherwise reports
|
|
26
|
-
* per-document failures without rejecting).
|
|
27
|
-
*/
|
|
28
|
-
export declare function importBatch(client: Client, collection: string, batch: readonly {
|
|
29
|
-
id: string;
|
|
30
|
-
}[]): Promise<void>;
|
|
31
|
-
//# sourceMappingURL=import.d.ts.map
|
package/dist/import.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../src/import.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,WAAW,CAAC;AAExD,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC;;;;GAIG;AACH,qBAAa,aAAa,CAAC,SAAS,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IAIvD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL5B,OAAO,CAAC,MAAM,CAAmB;gBAGd,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM;IAGpC,0EAA0E;IACpE,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAS7D,sCAAsC;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAMd,YAAY;CAK3B;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,GAC/B,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|