@lde/search-typesense 0.29.2 → 0.29.4
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.
|
@@ -73,7 +73,8 @@ export interface CollectionDefinitionOptions {
|
|
|
73
73
|
* size of the fields you search, facet or sort on – not the whole document.
|
|
74
74
|
* This builder keeps that surface minimal: the `output` display labels land in
|
|
75
75
|
* a single `index: false` regex field (`${name}_<lang>`, one value per present
|
|
76
|
-
* language
|
|
76
|
+
* language, or every value of it as a `string[]` for an `array` field), kept
|
|
77
|
+
* on disk and read back only for a hit, so they cost no RAM;
|
|
77
78
|
* only the folded `*_search_${locale}`, facet/reference and `*_sort_${locale}`
|
|
78
79
|
* companions are indexed. Keeping retrieval-only fields un-indexed is the lever
|
|
79
80
|
* for holding a large index’s RAM down.
|
|
@@ -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;AAcrB,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
|
|
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;AAcrB,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,CA2BxB"}
|
|
@@ -27,7 +27,8 @@ import { deriveCollectionName } from './collection-name.js';
|
|
|
27
27
|
* size of the fields you search, facet or sort on – not the whole document.
|
|
28
28
|
* This builder keeps that surface minimal: the `output` display labels land in
|
|
29
29
|
* a single `index: false` regex field (`${name}_<lang>`, one value per present
|
|
30
|
-
* language
|
|
30
|
+
* language, or every value of it as a `string[]` for an `array` field), kept
|
|
31
|
+
* on disk and read back only for a hit, so they cost no RAM;
|
|
31
32
|
* only the folded `*_search_${locale}`, facet/reference and `*_sort_${locale}`
|
|
32
33
|
* companions are indexed. Keeping retrieval-only fields un-indexed is the lever
|
|
33
34
|
* for holding a large index’s RAM down.
|
|
@@ -163,12 +164,14 @@ function typesenseFields(searchType, field, defaultLocale, defaultSortingField,
|
|
|
163
164
|
// the folded `*_search` companions, so the display copies stay on disk and
|
|
164
165
|
// off RAM (fetched only for a hit), accents preserved, and a language
|
|
165
166
|
// outside `locales` still renders. This is the memory lever: RAM tracks
|
|
166
|
-
// the search surface, not the display text. Absent for a non-output
|
|
167
|
+
// the search surface, not the display text. Absent for a non-output
|
|
168
|
+
// field. An `array` field stores every value of a language, so its
|
|
169
|
+
// pattern is typed a list – `array` decides the shape for every kind.
|
|
167
170
|
...(displayPattern !== undefined
|
|
168
171
|
? [
|
|
169
172
|
{
|
|
170
173
|
name: displayPattern,
|
|
171
|
-
type:
|
|
174
|
+
type: typesenseValueType(field),
|
|
172
175
|
index: false,
|
|
173
176
|
optional: true,
|
|
174
177
|
},
|
|
@@ -426,10 +429,11 @@ function nestedLeafFields(prefix, field, defaultLocale, flattensToArray) {
|
|
|
426
429
|
if (pattern !== undefined) {
|
|
427
430
|
// Display values are never indexed, whatever Roles the field declares:
|
|
428
431
|
// search hits the folded companions below, so the display copies stay on
|
|
429
|
-
// disk with every language they carry
|
|
432
|
+
// disk with every language they carry – every value of it for an
|
|
433
|
+
// `array` field.
|
|
430
434
|
fields.push({
|
|
431
435
|
name: nestedFieldName(prefix, pattern),
|
|
432
|
-
type:
|
|
436
|
+
type: typesenseValueType(field),
|
|
433
437
|
index: false,
|
|
434
438
|
optional: true,
|
|
435
439
|
});
|
package/dist/search.js
CHANGED
|
@@ -656,16 +656,20 @@ function logicalValue(flat, field, labels, schema, referents) {
|
|
|
656
656
|
* recovers languages outside the declared `locales` too – a value tagged in an
|
|
657
657
|
* undeclared language, or untagged (`und`), still reconstructs rather than being
|
|
658
658
|
* dropped.
|
|
659
|
+
*
|
|
660
|
+
* A display field holds one string for a plain field, or a list of them for an
|
|
661
|
+
* `array` field.
|
|
659
662
|
*/
|
|
660
663
|
function localizedValue(flat, field) {
|
|
661
664
|
const map = {};
|
|
662
665
|
for (const [key, value] of Object.entries(flat)) {
|
|
663
|
-
|
|
666
|
+
const lang = displayLangOf(field, key);
|
|
667
|
+
if (lang === undefined) {
|
|
664
668
|
continue;
|
|
665
669
|
}
|
|
666
|
-
const
|
|
667
|
-
if (
|
|
668
|
-
map[lang] =
|
|
670
|
+
const values = (Array.isArray(value) ? value : [value]).filter((entry) => typeof entry === 'string');
|
|
671
|
+
if (values.length > 0) {
|
|
672
|
+
map[lang] = values;
|
|
669
673
|
}
|
|
670
674
|
}
|
|
671
675
|
return Object.keys(map).length > 0 ? map : undefined;
|
|
@@ -694,31 +698,33 @@ function nestedValue(raw, field, referenceType, labels, schema, children) {
|
|
|
694
698
|
}
|
|
695
699
|
/**
|
|
696
700
|
* Rebuild a {@link ReferenceStrategy.local local} lookup: the endpoint’s own
|
|
697
|
-
* document as this document stated it,
|
|
701
|
+
* document as this document stated it, **replaced** by the resolved document
|
|
698
702
|
* where the lookup found one.
|
|
699
703
|
*
|
|
700
|
-
*
|
|
701
|
-
*
|
|
702
|
-
*
|
|
703
|
-
*
|
|
704
|
+
* Replaced rather than merged, because both sides are the target type’s flat
|
|
705
|
+
* physical shape and a logical field fans out into several physical ones: a
|
|
706
|
+
* name this document stated in one language would survive beside the target’s
|
|
707
|
+
* name in another, and a field the target’s record does not carry would
|
|
708
|
+
* survive after the target dropped it. The resolved document carries what the
|
|
709
|
+
* projection asked for, and a resolved entry says exactly that – what a plain
|
|
710
|
+
* lookup says too. Three cases fall out of one expression, which is the point
|
|
711
|
+
* of storing local fields unconditionally:
|
|
704
712
|
*
|
|
705
|
-
* - identified and indexed → the target’s own record
|
|
713
|
+
* - identified and indexed → the target’s own record;
|
|
706
714
|
* - identified but not indexed → what was stated here, plus the `id`, rather
|
|
707
715
|
* than a bare IRI;
|
|
708
716
|
* - not identified → what was stated here, with no `id` at all.
|
|
709
717
|
*/
|
|
710
718
|
function localLookupValue(raw, field, target, resolved, labels, schema) {
|
|
711
719
|
const fetched = resolved?.via === 'lookup' ? resolved.documents : new Map();
|
|
712
|
-
const
|
|
720
|
+
const entries = (Array.isArray(raw) ? raw : [raw])
|
|
713
721
|
.filter((entry) => typeof entry === 'object' && entry !== null)
|
|
714
722
|
.map((entry) => {
|
|
715
723
|
const id = typeof entry.id === 'string' ? entry.id : undefined;
|
|
716
724
|
const authoritative = id === undefined ? undefined : fetched.get(id);
|
|
717
|
-
return authoritative
|
|
718
|
-
? entry
|
|
719
|
-
: { ...entry, ...authoritative };
|
|
725
|
+
return authoritative ?? entry;
|
|
720
726
|
});
|
|
721
|
-
return nestedValue(
|
|
727
|
+
return nestedValue(entries, field, target, labels, schema, resolved?.children);
|
|
722
728
|
}
|
|
723
729
|
/**
|
|
724
730
|
* Rebuild a resolved `lookup` reference: each stored IRI becomes the referent’s
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lde/search-typesense",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.4",
|
|
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.24.
|
|
28
|
+
"@lde/search": "^0.24.4",
|
|
29
29
|
"@lde/text-normalization": "^0.1.2",
|
|
30
30
|
"tslib": "^2.3.0",
|
|
31
31
|
"typesense": "^3.0.6"
|