@lde/search-typesense 0.52.1 → 0.52.2
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/collection-definition.d.ts.map +1 -1
- package/dist/collection-definition.js +14 -2
- package/dist/in-place-rebuild.js +8 -10
- package/dist/query-compiler.d.ts.map +1 -1
- package/dist/query-compiler.js +6 -6
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +25 -21
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-definition.d.ts","sourceRoot":"","sources":["../src/collection-definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"collection-definition.d.ts","sourceRoot":"","sources":["../src/collection-definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAiBrB,0EAA0E;AAC1E,MAAM,WAAW,2BAA2B;IAC1C;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,MAAM,CAAC;IAChE;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B;;;4BAGwB;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,kEAAkE;IAClE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,2BAAgC,GACxC,sBAAsB,CAwCxB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { displayFieldPattern, ID_FIELD, isInlineReference, isInternalField, isBinnedRangeFacet, joinGraph, localLookupTargetsOf, TARGET_FIELD, nestedFieldName, nestedReferenceType, physicalFields, } from '@lde/search/adapter';
|
|
1
|
+
import { displayFieldPattern, facetsOf, ID_FIELD, isInlineReference, isInternalField, isBinnedRangeFacet, joinGraph, localLookupTargetsOf, TARGET_FIELD, nestedFieldName, nestedReferenceType, physicalFields, } from '@lde/search/adapter';
|
|
2
2
|
import { deriveCollectionName } from './collection-name.js';
|
|
3
3
|
/**
|
|
4
4
|
* Build a Typesense collection definition from the unified {@link SearchType}, so
|
|
@@ -56,6 +56,16 @@ export function buildCollectionDefinition(searchType, options = {}) {
|
|
|
56
56
|
name: collectionNameFor(searchType),
|
|
57
57
|
fields: searchType.fields.flatMap((field) => typesenseFields(searchType, field, defaultLocale, options.defaultSortingField, options.schema, collectionNameFor)),
|
|
58
58
|
};
|
|
59
|
+
// A faceted leaf is faceted on its nested path, which Typesense flattens
|
|
60
|
+
// into one list per document – so a bucket counts documents, not entries.
|
|
61
|
+
const facetedPaths = new Set(facetsOf(searchType, options.schema)
|
|
62
|
+
.filter((facet) => facet.reference !== undefined)
|
|
63
|
+
.map((facet) => facet.engineField));
|
|
64
|
+
for (const field of collection.fields) {
|
|
65
|
+
if (facetedPaths.has(field.name)) {
|
|
66
|
+
field.facet = true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
59
69
|
// Typesense rejects an `object`/`object[]` field unless nesting is enabled,
|
|
60
70
|
// so the flag is a consequence of the declaration – never a knob.
|
|
61
71
|
if (collection.fields?.some((field) => field.type.startsWith('object'))) {
|
|
@@ -589,7 +599,9 @@ function nestedLeafFields(prefix, field, defaultLocale, flattensToArray) {
|
|
|
589
599
|
}
|
|
590
600
|
// A nested field can be `filterable` or `searchable`, never `facetable` or
|
|
591
601
|
// `sortable` (`searchSchema`), so `filterable` is what indexes the value
|
|
592
|
-
// itself – its search companion below indexes on its own account.
|
|
602
|
+
// itself – its search companion below indexes on its own account. A leaf the
|
|
603
|
+
// root is faceted on is marked a facet field once the collection is built
|
|
604
|
+
// ({@link buildCollectionDefinition}), since only the root knows.
|
|
593
605
|
const indexed = field.filterable === true;
|
|
594
606
|
const valueType = typesenseValueType(field);
|
|
595
607
|
// Two ways a list arrives: the field declares one, or an ancestor's
|
package/dist/in-place-rebuild.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { facetsOf } from '@lde/search/adapter';
|
|
2
2
|
import { buildCollectionDefinition } from './collection-definition.js';
|
|
3
3
|
import { ensureCollectionExists, openLockedRun, releaseLock } from './lock.js';
|
|
4
4
|
import { assertBookkeepingPresent, assertWritableType, openDocuments, withBookkeeping, } from './documents.js';
|
|
@@ -176,16 +176,14 @@ function assertReferencesAndFacetCompanionsPresent(name, fields, facetCompanions
|
|
|
176
176
|
if (missingCompanions.length > 0) {
|
|
177
177
|
throw new Error(`Typesense collection “${name}” exists without the facet field(s) ${missingCompanions
|
|
178
178
|
.map((companion) => `“${companion}”`)
|
|
179
|
-
.join(', ')} its search type facets on in place of the field itself – an identity companion,
|
|
179
|
+
.join(', ')} its search type facets on in place of the field itself – an identity companion, one narrowed by a facet policy (“facetKeys”), or the nested path of a faceted leaf. A facet field cannot be added to a live collection here: drop “${name}” (and the collections that join to it) and let the next run rebuild them.`);
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
-
/** The
|
|
183
|
-
*
|
|
184
|
-
*
|
|
182
|
+
/** The fields a type’s facets read instead of the fields themselves – one per
|
|
183
|
+
* facetable reference that stores a nested object or inherits a facet policy
|
|
184
|
+
* ({@link facetsOf}), and the nested path of each faceted leaf. */
|
|
185
185
|
function facetCompanionsOf(searchType, schema) {
|
|
186
|
-
return
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return facet === field.name ? [] : [facet];
|
|
190
|
-
});
|
|
186
|
+
return facetsOf(searchType, schema)
|
|
187
|
+
.filter((facet) => facet.engineField !== facet.field.name)
|
|
188
|
+
.map((facet) => facet.engineField);
|
|
191
189
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-compiler.d.ts","sourceRoot":"","sources":["../src/query-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAEzE,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,QAAQ,EAEb,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,UAAU,EAIhB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"query-compiler.d.ts","sourceRoot":"","sources":["../src/query-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAEzE,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,QAAQ,EAEb,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,UAAU,EAIhB,MAAM,aAAa,CAAC;AAuBrB;mDACmD;AACnD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CACvB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,SAAS,MAAM,EAAE,KACpB,UAAU,GAAG,SAAS,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;;;;OAQG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,wBAA6B,GACrC,YAAY,CAAC,MAAM,CAAC,CAkCtB;AAikBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD"}
|
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, storedFacetRanges, storedRangeBound, isInternalField, isBinnedRangeFacet, holdsNoIds, isWelded, joinGraph, localLookupTargetsOf, matchLanguage, pageForOffset, physicalFields, nestedReferenceType, resolvePath, searchableFields, } from '@lde/search/adapter';
|
|
2
|
+
import { fieldNamed, filterOperator, filterOperatorFor, ID_FIELD, storedFacetRanges, storedRangeBound, isInternalField, isBinnedRangeFacet, facetNamed, holdsNoIds, isWelded, joinGraph, localLookupTargetsOf, matchLanguage, 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),
|
|
@@ -56,13 +56,13 @@ export function buildSearchParams(query, searchType, options = {}) {
|
|
|
56
56
|
function compileFacetBy(facets, searchType, schema) {
|
|
57
57
|
return facets
|
|
58
58
|
.map((name) => {
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
59
|
+
const facet = facetNamed(searchType, name, schema);
|
|
60
|
+
if (facet === undefined) {
|
|
61
61
|
return name;
|
|
62
62
|
}
|
|
63
|
-
return isBinnedRangeFacet(field)
|
|
64
|
-
? compileRangeFacet(
|
|
65
|
-
:
|
|
63
|
+
return isBinnedRangeFacet(facet.field)
|
|
64
|
+
? compileRangeFacet(facet.engineField, storedFacetRanges(facet.field))
|
|
65
|
+
: facet.engineField;
|
|
66
66
|
})
|
|
67
67
|
.join(',');
|
|
68
68
|
}
|
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;AACxC,OAAO,EAIL,KAAK,cAAc,EAMnB,KAAK,UAAU,EAGf,KAAK,YAAY,EAEjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,UAAU,EAEf,KAAK,SAAS,EACf,MAAM,aAAa,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,5 +1,5 @@
|
|
|
1
1
|
import { NESTED_DOCUMENT_TYPE, } from '@lde/search';
|
|
2
|
-
import { assertTypeInSchema, assertValidQuery, displayLangOf,
|
|
2
|
+
import { assertTypeInSchema, assertValidQuery, displayLangOf, facetNamed, facetSearches, facetsOf, selectionOf, fieldNamed, inheritedFacetPolicies, isDatePrecision, isInlineReference, isBinnedRangeFacet, isUnsatisfiable, joinGraph, labelFieldOf, labelSourceNamesOf, labelTargetNamesOf, literalKindOf, localLookupTargetsOf, nestedReferenceType, outputFields, physicalFields, referencedTargetsOf, referenceFields, storedFacetRanges, storedTargetOf, } from '@lde/search/adapter';
|
|
3
3
|
import { buildSearchParams, escapeFilterValue, } from './query-compiler.js';
|
|
4
4
|
import { deriveCollectionName } from './collection-name.js';
|
|
5
5
|
import { resolveProjection, } from './lookup.js';
|
|
@@ -70,13 +70,20 @@ export function createTypesenseSearchEngine(client, schema, options = {}) {
|
|
|
70
70
|
// reference naming several targets reads labels from every one of them.
|
|
71
71
|
const labelSources = new Map([...schema.values()].map((searchType) => [
|
|
72
72
|
searchType.class,
|
|
73
|
-
new Map(
|
|
73
|
+
new Map([
|
|
74
|
+
...referenceFields(searchType).map((field) => ({
|
|
75
|
+
name: field.name,
|
|
76
|
+
field,
|
|
77
|
+
})),
|
|
78
|
+
// A faceted leaf labels its buckets from the leaf’s own targets.
|
|
79
|
+
...facetsOf(searchType, schema).filter((facet) => facet.reference !== undefined),
|
|
80
|
+
]
|
|
74
81
|
// An INLINE reference names its label target one level in, through
|
|
75
82
|
// its identity companion: the companion holds that field's ids, so
|
|
76
83
|
// that field's target is what can label them.
|
|
77
|
-
.filter((field) => labelTargetNamesOf(field, schema).length > 0)
|
|
78
|
-
.map((field) => [
|
|
79
|
-
|
|
84
|
+
.filter(({ field }) => labelTargetNamesOf(field, schema).length > 0)
|
|
85
|
+
.map(({ name, field }) => [
|
|
86
|
+
name,
|
|
80
87
|
labelTargetNamesOf(field, schema).map((targetName) => {
|
|
81
88
|
const source = typesByName.get(targetName);
|
|
82
89
|
const labelField = labelFieldOf(source);
|
|
@@ -98,10 +105,9 @@ export function createTypesenseSearchEngine(client, schema, options = {}) {
|
|
|
98
105
|
// facet’s labels, or its counts, or both.
|
|
99
106
|
const declaredFacetNames = new Map([...schema.values()].map((searchType) => [
|
|
100
107
|
searchType.class,
|
|
101
|
-
new Map(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
field.name,
|
|
108
|
+
new Map(facetsOf(searchType, schema).map((facet) => [
|
|
109
|
+
facet.engineField,
|
|
110
|
+
facet.name,
|
|
105
111
|
])),
|
|
106
112
|
]));
|
|
107
113
|
// The distinct source collections per type, for the cached path – fixed at
|
|
@@ -577,7 +583,12 @@ async function withSelectedValues(client, collection, searchType, entries, optio
|
|
|
577
583
|
collection,
|
|
578
584
|
...buildSearchParams({
|
|
579
585
|
...query,
|
|
580
|
-
where: [
|
|
586
|
+
where: [
|
|
587
|
+
...query.where,
|
|
588
|
+
// Only a facet the query asked for, and `assertValidQuery`
|
|
589
|
+
// admitted, is counted value by value.
|
|
590
|
+
selectionOf(facetNamed(searchType, field, options.schema), value),
|
|
591
|
+
],
|
|
581
592
|
facets: [],
|
|
582
593
|
orderBy: [],
|
|
583
594
|
limit: 0,
|
|
@@ -634,13 +645,6 @@ async function withSelectedValues(client, collection, searchType, entries, optio
|
|
|
634
645
|
};
|
|
635
646
|
});
|
|
636
647
|
}
|
|
637
|
-
/** The clause that selects one facet value: `is` on a boolean, `in` on
|
|
638
|
-
* anything else. */
|
|
639
|
-
function selecting(searchType, field, value) {
|
|
640
|
-
return filterOn(fieldNamed(searchType, field)?.kind === 'boolean'
|
|
641
|
-
? { field, is: value === 'true' }
|
|
642
|
-
: { field, in: [value] });
|
|
643
|
-
}
|
|
644
648
|
/** Orders buckets by descending count, as the engine orders its own. */
|
|
645
649
|
function byCount(first, second) {
|
|
646
650
|
return second.count - first.count;
|
|
@@ -757,16 +761,16 @@ export function parseSearchResponse(response, searchType, labels, schema, refere
|
|
|
757
761
|
// Only reference facets with a label source get bucket labels; an id-only
|
|
758
762
|
// reference facet stays id-only even when a cached full-collection map holds
|
|
759
763
|
// its IRIs.
|
|
760
|
-
const referenceFacets = new Set(
|
|
761
|
-
.filter((
|
|
762
|
-
.map((
|
|
764
|
+
const referenceFacets = new Set(facetsOf(searchType, schema)
|
|
765
|
+
.filter((facet) => labelTargetNamesOf(facet.field, schema).length > 0)
|
|
766
|
+
.map((facet) => facet.name));
|
|
763
767
|
const facets = {};
|
|
764
768
|
for (const facet of response.facet_counts ?? []) {
|
|
765
769
|
const labelled = referenceFacets.has(facet.field_name);
|
|
766
770
|
// A binned facet echoes the declared range key as the bucket value; look
|
|
767
771
|
// the bin’s half-open bounds back up by key, in stored terms, so the
|
|
768
772
|
// bucket is self-describing.
|
|
769
|
-
const field =
|
|
773
|
+
const field = facetNamed(searchType, facet.field_name, schema)?.field;
|
|
770
774
|
const rangesByKey = field !== undefined && isBinnedRangeFacet(field)
|
|
771
775
|
? new Map(storedFacetRanges(field).map((range) => [range.key, range]))
|
|
772
776
|
: undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lde/search-typesense",
|
|
3
|
-
"version": "0.52.
|
|
3
|
+
"version": "0.52.2",
|
|
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,7 +25,7 @@
|
|
|
25
25
|
"!**/*.tsbuildinfo"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@lde/search": "^0.41.
|
|
28
|
+
"@lde/search": "^0.41.3",
|
|
29
29
|
"@lde/text-normalization": "^0.3.0",
|
|
30
30
|
"tslib": "^2.3.0",
|
|
31
31
|
"typesense": "^3.2.0"
|