@usereactify/search 5.60.0-beta.1 → 5.60.0-beta.3
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/CHANGELOG.md +9 -0
- package/dist/package.json +1 -1
- package/dist/src/components/Example/ExampleProductCardWeight.js +14 -19
- package/dist/src/components/Example/ExampleProductCardWeight.js.map +1 -1
- package/dist/src/utility/weight.d.ts +7 -0
- package/dist/src/utility/weight.js +98 -14
- package/dist/src/utility/weight.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [5.60.0-beta.3](///compare/beta-v5.60.0-beta.2...beta-v5.60.0-beta.3) (2026-01-16)
|
|
6
|
+
|
|
7
|
+
## [5.60.0-beta.2](///compare/beta-v5.60.0-beta.1...beta-v5.60.0-beta.2) (2026-01-15)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* add term-level tracking and formatting for weight breakdown 949e7e9
|
|
13
|
+
|
|
5
14
|
## [5.60.0-beta.1](///compare/beta-v5.59.0-beta.8...beta-v5.60.0-beta.1) (2026-01-15)
|
|
6
15
|
|
|
7
16
|
|
package/dist/package.json
CHANGED
|
@@ -35,43 +35,38 @@ const ExampleProductCardWeight = ({ document }) => {
|
|
|
35
35
|
const weight = (0, react_1.useMemo)(() => (explanation ? (0, utility_1.getWeight)(explanation) : document._score), [explanation, document._score]);
|
|
36
36
|
// Parse the weight breakdown if available
|
|
37
37
|
const weightBreakdown = (0, react_1.useMemo)(() => (explanation ? (0, utility_1.explainWeight)(explanation) : []), [explanation]);
|
|
38
|
+
// Memoized formatted breakdown for performance
|
|
39
|
+
const formattedBreakdown = (0, react_1.useMemo)(() => (0, utility_1.formatWeightBreakdown)(weightBreakdown), [weightBreakdown]);
|
|
38
40
|
const toggleWeightBreakdown = () => setShowWeightBreakdown(!showWeightBreakdown);
|
|
39
41
|
if (!options.devMode)
|
|
40
42
|
return null;
|
|
41
43
|
if (!weight)
|
|
42
44
|
return null;
|
|
43
45
|
return (react_1.default.createElement("div", { className: "rs__result-card-product__weight", onClick: toggleWeightBreakdown, style: {
|
|
44
|
-
background: "
|
|
45
|
-
borderRadius: "
|
|
46
|
+
background: "linear-gradient(135deg, #7858F7 0%, #9174ff 100%)",
|
|
47
|
+
borderRadius: "6px",
|
|
46
48
|
color: "white",
|
|
47
49
|
cursor: "pointer",
|
|
48
|
-
|
|
49
|
-
fontSize: "11px",
|
|
50
|
-
fontWeight: "bold",
|
|
50
|
+
fontSize: "12px",
|
|
51
51
|
maxWidth: "100%",
|
|
52
|
-
padding: "
|
|
52
|
+
padding: "6px",
|
|
53
53
|
} },
|
|
54
|
-
react_1.default.createElement("div",
|
|
54
|
+
react_1.default.createElement("div", { style: { fontWeight: "bold" } },
|
|
55
55
|
"Weight: ",
|
|
56
56
|
weight.toFixed(2)),
|
|
57
57
|
showWeightBreakdown && weightBreakdown.length > 0 && (react_1.default.createElement("div", { style: {
|
|
58
58
|
backgroundColor: "rgba(255, 255, 255, 0.95)",
|
|
59
|
-
border: "1px solid #
|
|
60
|
-
borderRadius: "
|
|
59
|
+
border: "1px solid #e0e0e0",
|
|
60
|
+
borderRadius: "6px",
|
|
61
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
61
62
|
color: "black",
|
|
62
|
-
fontSize: "
|
|
63
|
-
marginTop: "
|
|
63
|
+
fontSize: "12px",
|
|
64
|
+
marginTop: "6px",
|
|
64
65
|
maxHeight: "150px",
|
|
65
66
|
overflowY: "auto",
|
|
66
|
-
padding: "
|
|
67
|
+
padding: "6px",
|
|
67
68
|
} },
|
|
68
|
-
react_1.default.createElement("
|
|
69
|
-
weightBreakdown.map((item, index) => (react_1.default.createElement("div", { key: index, style: { marginBottom: "2px" } },
|
|
70
|
-
react_1.default.createElement("strong", null,
|
|
71
|
-
item.field,
|
|
72
|
-
":"),
|
|
73
|
-
" ",
|
|
74
|
-
item.weight.toFixed(2))))))));
|
|
69
|
+
react_1.default.createElement("div", { style: { whiteSpace: "pre-line" } }, formattedBreakdown)))));
|
|
75
70
|
};
|
|
76
71
|
exports.ExampleProductCardWeight = ExampleProductCardWeight;
|
|
77
72
|
//# sourceMappingURL=ExampleProductCardWeight.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExampleProductCardWeight.js","sourceRoot":"","sources":["../../../../src/components/Example/ExampleProductCardWeight.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiD;AAEjD,uCAAuD;AACvD,
|
|
1
|
+
{"version":3,"file":"ExampleProductCardWeight.js","sourceRoot":"","sources":["../../../../src/components/Example/ExampleProductCardWeight.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiD;AAEjD,uCAAuD;AACvD,2CAMuB;AAOhB,MAAM,wBAAwB,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE;IACtF,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,gCAAwB,GAAE,CAAC;IAC/C,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAEtE,8CAA8C;IAC9C,MAAM,WAAW,GAAG,QAAQ,CAAC,YAAY,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAA,eAAO,EACpB,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAA,mBAAS,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAC9D,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAC/B,CAAC;IAEF,0CAA0C;IAC1C,MAAM,eAAe,GAA0B,IAAA,eAAO,EACpD,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAA,uBAAa,EAAC,WAAiC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAC3E,CAAC,WAAW,CAAC,CACd,CAAC;IAEF,+CAA+C;IAC/C,MAAM,kBAAkB,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,IAAA,+BAAqB,EAAC,eAAe,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAEpG,MAAM,qBAAqB,GAAG,GAAG,EAAE,CAAC,sBAAsB,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAEjF,IAAI,CAAC,OAAO,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAElC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,OAAO,CACL,uCACE,SAAS,EAAC,iCAAiC,EAC3C,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE;YACL,UAAU,EAAE,mDAAmD;YAC/D,YAAY,EAAE,KAAK;YACnB,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,SAAS;YACjB,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,KAAK;SACf;QAED,uCAAK,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;;YAAW,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAO;QAEpE,mBAAmB,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CACpD,uCACE,KAAK,EAAE;gBACL,eAAe,EAAE,2BAA2B;gBAC5C,MAAM,EAAE,mBAAmB;gBAC3B,YAAY,EAAE,KAAK;gBACnB,SAAS,EAAE,gCAAgC;gBAC3C,KAAK,EAAE,OAAO;gBACd,QAAQ,EAAE,MAAM;gBAChB,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,OAAO;gBAClB,SAAS,EAAE,MAAM;gBACjB,OAAO,EAAE,KAAK;aACf;YAED,uCAAK,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,IAAG,kBAAkB,CAAO,CAC9D,CACP,CACG,CACP,CAAC;AACJ,CAAC,CAAC;AA9DW,QAAA,wBAAwB,4BA8DnC","sourcesContent":["import React, { useState, useMemo } from \"react\";\n\nimport { useReactifySearchContext } from \"../../hooks\";\nimport {\n explainWeight,\n getWeight,\n ExplainScoreDetail,\n ExplainParsedWeight,\n formatWeightBreakdown,\n} from \"../../utility\";\nimport { ElasticProduct } from \"../../types\";\n\nexport interface ExampleProductCardWeightProps {\n document: ElasticProduct;\n}\n\nexport const ExampleProductCardWeight = ({ document }: ExampleProductCardWeightProps) => {\n const { options } = useReactifySearchContext();\n const [showWeightBreakdown, setShowWeightBreakdown] = useState(false);\n\n // Extract score and explanation from document\n const explanation = document._explanation;\n const weight = useMemo(\n () => (explanation ? getWeight(explanation) : document._score),\n [explanation, document._score],\n );\n\n // Parse the weight breakdown if available\n const weightBreakdown: ExplainParsedWeight[] = useMemo(\n () => (explanation ? explainWeight(explanation as ExplainScoreDetail) : []),\n [explanation],\n );\n\n // Memoized formatted breakdown for performance\n const formattedBreakdown = useMemo(() => formatWeightBreakdown(weightBreakdown), [weightBreakdown]);\n\n const toggleWeightBreakdown = () => setShowWeightBreakdown(!showWeightBreakdown);\n\n if (!options.devMode) return null;\n\n if (!weight) return null;\n\n return (\n <div\n className=\"rs__result-card-product__weight\"\n onClick={toggleWeightBreakdown}\n style={{\n background: \"linear-gradient(135deg, #7858F7 0%, #9174ff 100%)\",\n borderRadius: \"6px\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"12px\",\n maxWidth: \"100%\",\n padding: \"6px\",\n }}\n >\n <div style={{ fontWeight: \"bold\" }}>Weight: {weight.toFixed(2)}</div>\n\n {showWeightBreakdown && weightBreakdown.length > 0 && (\n <div\n style={{\n backgroundColor: \"rgba(255, 255, 255, 0.95)\",\n border: \"1px solid #e0e0e0\",\n borderRadius: \"6px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n color: \"black\",\n fontSize: \"12px\",\n marginTop: \"6px\",\n maxHeight: \"150px\",\n overflowY: \"auto\",\n padding: \"6px\",\n }}\n >\n <div style={{ whiteSpace: \"pre-line\" }}>{formattedBreakdown}</div>\n </div>\n )}\n </div>\n );\n};\n"]}
|
|
@@ -3,9 +3,16 @@ export type ExplainScoreDetail = {
|
|
|
3
3
|
description: string;
|
|
4
4
|
details?: ExplainScoreDetail[];
|
|
5
5
|
};
|
|
6
|
+
export type ExplainParsedTerm = {
|
|
7
|
+
term: string;
|
|
8
|
+
weight: number;
|
|
9
|
+
isSynonym: boolean;
|
|
10
|
+
};
|
|
6
11
|
export type ExplainParsedWeight = {
|
|
7
12
|
field: string;
|
|
8
13
|
weight: number;
|
|
14
|
+
terms: ExplainParsedTerm[];
|
|
9
15
|
};
|
|
10
16
|
export declare function getWeight(explanation: ExplainScoreDetail): number;
|
|
11
17
|
export declare function explainWeight(explanation: ExplainScoreDetail): ExplainParsedWeight[];
|
|
18
|
+
export declare function formatWeightBreakdown(weights: ExplainParsedWeight[]): string;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getWeight = getWeight;
|
|
4
4
|
exports.explainWeight = explainWeight;
|
|
5
|
+
exports.formatWeightBreakdown = formatWeightBreakdown;
|
|
5
6
|
function getWeight(explanation) {
|
|
6
7
|
var _a;
|
|
7
8
|
const detail = (_a = explanation.details) === null || _a === void 0 ? void 0 : _a.find((detail) => detail.description === "min of:");
|
|
@@ -24,15 +25,23 @@ function parseWeights(detail) {
|
|
|
24
25
|
if (subDetail.details) {
|
|
25
26
|
for (const functionDetail of subDetail.details) {
|
|
26
27
|
if (functionDetail.description.includes("match filter:")) {
|
|
27
|
-
const
|
|
28
|
-
if (
|
|
29
|
-
parsedWeights.push({
|
|
28
|
+
const fieldTermData = extractFieldWithTerm(functionDetail.description);
|
|
29
|
+
if (fieldTermData) {
|
|
30
|
+
parsedWeights.push({
|
|
31
|
+
field: fieldTermData.field,
|
|
32
|
+
weight: 0, // Will be calculated in mergeWeights
|
|
33
|
+
terms: [{ term: fieldTermData.term, weight: parentWeight, isSynonym: fieldTermData.isSynonym }],
|
|
34
|
+
});
|
|
30
35
|
}
|
|
31
36
|
}
|
|
32
37
|
if (functionDetail.description.includes("weight")) {
|
|
33
38
|
const field = extractFieldNameFromDetails(functionDetail);
|
|
34
39
|
if (field && field !== "unknown") {
|
|
35
|
-
parsedWeights.push({
|
|
40
|
+
parsedWeights.push({
|
|
41
|
+
field,
|
|
42
|
+
weight: 0, // Will be calculated in mergeWeights
|
|
43
|
+
terms: [{ term: "unknown", weight: parentWeight, isSynonym: false }],
|
|
44
|
+
});
|
|
36
45
|
}
|
|
37
46
|
}
|
|
38
47
|
}
|
|
@@ -48,15 +57,23 @@ function parseWeights(detail) {
|
|
|
48
57
|
if (detail.details) {
|
|
49
58
|
for (const subDetail of detail.details) {
|
|
50
59
|
if (subDetail.description.includes("match filter:")) {
|
|
51
|
-
const
|
|
52
|
-
if (
|
|
53
|
-
parsedWeights.push({
|
|
60
|
+
const fieldTermData = extractFieldWithTerm(subDetail.description);
|
|
61
|
+
if (fieldTermData) {
|
|
62
|
+
parsedWeights.push({
|
|
63
|
+
field: fieldTermData.field,
|
|
64
|
+
weight: 0, // Will be calculated in mergeWeights
|
|
65
|
+
terms: [{ term: fieldTermData.term, weight: parentWeight, isSynonym: fieldTermData.isSynonym }],
|
|
66
|
+
});
|
|
54
67
|
}
|
|
55
68
|
}
|
|
56
69
|
if (subDetail.description.includes("weight")) {
|
|
57
70
|
const field = extractFieldNameFromDetails(subDetail);
|
|
58
71
|
if (field && field !== "unknown") {
|
|
59
|
-
parsedWeights.push({
|
|
72
|
+
parsedWeights.push({
|
|
73
|
+
field,
|
|
74
|
+
weight: 0, // Will be calculated in mergeWeights
|
|
75
|
+
terms: [{ term: "unknown", weight: parentWeight, isSynonym: false }],
|
|
76
|
+
});
|
|
60
77
|
}
|
|
61
78
|
}
|
|
62
79
|
}
|
|
@@ -117,6 +134,49 @@ function extractFieldFromMatchFilter(description) {
|
|
|
117
134
|
}
|
|
118
135
|
return null;
|
|
119
136
|
}
|
|
137
|
+
function extractTermFromFilter(description) {
|
|
138
|
+
// Extract from excluded terms in synonym queries: -field:term
|
|
139
|
+
const excludedMatch = description.match(/-([a-zA-Z_]+):([^)\s]+)/);
|
|
140
|
+
if (excludedMatch) {
|
|
141
|
+
const term = excludedMatch[2];
|
|
142
|
+
if (term.includes("freq") || term.includes("*") || term.includes("_all")) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
return { term, isSynonym: true };
|
|
146
|
+
}
|
|
147
|
+
// Extract from direct matches: field:term (but not parenthesized synonyms)
|
|
148
|
+
const directMatch = description.match(/match filter: ([a-zA-Z_]+):([^(\s]+)/);
|
|
149
|
+
if (directMatch) {
|
|
150
|
+
const term = directMatch[2];
|
|
151
|
+
if (term.includes("freq") || term.includes("*") || term.includes("_all")) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
return { term, isSynonym: false };
|
|
155
|
+
}
|
|
156
|
+
// Extract from parenthesized direct matches: (field:term)
|
|
157
|
+
const parenthesizedMatch = description.match(/match filter: \(([a-zA-Z_]+):([^)\s]+)/);
|
|
158
|
+
if (parenthesizedMatch) {
|
|
159
|
+
const term = parenthesizedMatch[2];
|
|
160
|
+
if (term.includes("freq") || term.includes("*") || term.includes("_all")) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
return { term, isSynonym: false };
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
function extractFieldWithTerm(description) {
|
|
168
|
+
const termData = extractTermFromFilter(description);
|
|
169
|
+
if (!termData)
|
|
170
|
+
return null;
|
|
171
|
+
const fieldData = extractFieldFromMatchFilter(description);
|
|
172
|
+
if (!fieldData)
|
|
173
|
+
return null;
|
|
174
|
+
return {
|
|
175
|
+
field: fieldData,
|
|
176
|
+
term: termData.term,
|
|
177
|
+
isSynonym: termData.isSynonym,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
120
180
|
function extractFieldNameFromDetails(detail) {
|
|
121
181
|
const description = detail.description.toLowerCase();
|
|
122
182
|
// Filter out undesired values
|
|
@@ -148,14 +208,38 @@ function extractFieldNameFromDetails(detail) {
|
|
|
148
208
|
}
|
|
149
209
|
function mergeWeights(weights) {
|
|
150
210
|
const mergedWeights = {};
|
|
211
|
+
// Merge by field, then by term
|
|
151
212
|
for (const weight of weights) {
|
|
152
|
-
|
|
153
|
-
mergedWeights[weight.field]
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
mergedWeights[weight.field]
|
|
213
|
+
for (const term of weight.terms) {
|
|
214
|
+
if (!mergedWeights[weight.field]) {
|
|
215
|
+
mergedWeights[weight.field] = {};
|
|
216
|
+
}
|
|
217
|
+
if (mergedWeights[weight.field][term.term]) {
|
|
218
|
+
mergedWeights[weight.field][term.term].weight += term.weight;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
mergedWeights[weight.field][term.term] = Object.assign({}, term);
|
|
222
|
+
}
|
|
157
223
|
}
|
|
158
224
|
}
|
|
159
|
-
|
|
225
|
+
// Convert back to array format and sort terms by weight
|
|
226
|
+
const result = [];
|
|
227
|
+
for (const [field, terms] of Object.entries(mergedWeights)) {
|
|
228
|
+
const termArray = Object.values(terms).sort((a, b) => b.weight - a.weight);
|
|
229
|
+
const totalWeight = termArray.reduce((sum, term) => sum + term.weight, 0);
|
|
230
|
+
result.push({ field, weight: totalWeight, terms: termArray });
|
|
231
|
+
}
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
234
|
+
function formatWeightBreakdown(weights) {
|
|
235
|
+
return weights
|
|
236
|
+
.sort((a, b) => b.weight - a.weight)
|
|
237
|
+
.map((weight) => {
|
|
238
|
+
const termBreakdown = weight.terms
|
|
239
|
+
.map((term) => `${term.term}: ${term.weight.toFixed(2)}${term.isSynonym ? " [synonym]" : ""}`)
|
|
240
|
+
.join(", ");
|
|
241
|
+
return `${weight.field}: ${weight.weight.toFixed(2)} (${termBreakdown})`;
|
|
242
|
+
})
|
|
243
|
+
.join("\n");
|
|
160
244
|
}
|
|
161
245
|
//# sourceMappingURL=weight.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"weight.js","sourceRoot":"","sources":["../../../src/utility/weight.ts"],"names":[],"mappings":"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","sourcesContent":["export type ExplainScoreDetail = {\n value: number;\n description: string;\n details?: ExplainScoreDetail[];\n};\n\nexport type ExplainParsedWeight = {\n field: string;\n weight: number;\n};\n\nexport function getWeight(explanation: ExplainScoreDetail): number {\n const detail = explanation.details?.find((detail) => detail.description === \"min of:\");\n return detail ? detail.value : explanation.value;\n}\n\nexport function explainWeight(explanation: ExplainScoreDetail): ExplainParsedWeight[] {\n const fieldWeights = parseWeights(explanation);\n const mergedWeights = mergeWeights(fieldWeights);\n const sortedWeights = mergedWeights.sort((a, b) => b.weight - a.weight);\n\n return sortedWeights;\n}\n\nfunction parseWeights(detail: ExplainScoreDetail): ExplainParsedWeight[] {\n const parsedWeights: ExplainParsedWeight[] = [];\n\n // Look for min_of score which contains the clean field weights\n if (detail.description.includes(\"min of:\")) {\n if (detail.details) {\n for (const subDetail of detail.details) {\n if (subDetail.description.includes(\"function score\") && subDetail.description.includes(\"product of:\")) {\n const parentWeight = subDetail.value;\n\n if (subDetail.details) {\n for (const functionDetail of subDetail.details) {\n if (functionDetail.description.includes(\"match filter:\")) {\n const field = extractFieldFromMatchFilter(functionDetail.description);\n if (field) {\n parsedWeights.push({ field, weight: parentWeight });\n }\n }\n\n if (functionDetail.description.includes(\"weight\")) {\n const field = extractFieldNameFromDetails(functionDetail);\n if (field && field !== \"unknown\") {\n parsedWeights.push({ field, weight: parentWeight });\n }\n }\n }\n }\n }\n }\n }\n }\n\n // Fallback to original parsing if min_of is not found\n if (parsedWeights.length === 0) {\n if (detail.description.includes(\"function score\") && detail.description.includes(\"product of:\")) {\n const parentWeight = detail.value;\n\n if (detail.details) {\n for (const subDetail of detail.details) {\n if (subDetail.description.includes(\"match filter:\")) {\n const field = extractFieldFromMatchFilter(subDetail.description);\n if (field) {\n parsedWeights.push({ field, weight: parentWeight });\n }\n }\n\n if (subDetail.description.includes(\"weight\")) {\n const field = extractFieldNameFromDetails(subDetail);\n if (field && field !== \"unknown\") {\n parsedWeights.push({ field, weight: parentWeight });\n }\n }\n }\n }\n }\n }\n\n if (detail.details) {\n for (const subDetail of detail.details) {\n parsedWeights.push(...parseWeights(subDetail));\n }\n }\n\n return parsedWeights;\n}\n\nfunction extractFieldFromMatchFilter(description: string): string | null {\n const lowerDescription = description.toLowerCase();\n\n // Filter out undesired values early\n if (\n lowerDescription.includes(\"freq\") ||\n lowerDescription.includes(\"perfieldsimilarity\") ||\n lowerDescription.includes(\"*:*\") ||\n lowerDescription.includes(\"_all\")\n ) {\n return null;\n }\n\n // Handle synonym queries: +Synonym(tags_colour:atlantic tags_colour:emerald ...) -tags_colour:green\n const synonymMatch = description.match(/\\+Synonym\\(([^:]+):/);\n if (synonymMatch) {\n const field = synonymMatch[1];\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return null;\n }\n return field;\n }\n\n // Handle simple match filters: match filter: title:shirt\n const simpleMatch = description.match(/match filter: ([a-zA-Z_]+):/);\n if (simpleMatch) {\n const field = simpleMatch[1];\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return null;\n }\n return field;\n }\n\n // Handle parenthesized match filters: match filter: (product_type:shirts)\n const parenthesizedMatch = description.match(/match filter: \\(([^:]+):/);\n if (parenthesizedMatch) {\n const field = parenthesizedMatch[1];\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return null;\n }\n return field;\n }\n\n // Handle complex queries with boosts: title:shirt (title:short)^0.8\n const complexMatch = description.match(/match filter: ([a-zA-Z_]+):[^(]+/);\n if (complexMatch) {\n const field = complexMatch[1];\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return null;\n }\n return field;\n }\n\n return null;\n}\n\nfunction extractFieldNameFromDetails(detail: ExplainScoreDetail): string {\n const description = detail.description.toLowerCase();\n\n // Filter out undesired values\n if (\n description.includes(\"freq\") ||\n description.includes(\"perfieldsimilarity\") ||\n description.includes(\"*:*\") ||\n description.includes(\"_all\")\n ) {\n return \"unknown\";\n }\n\n const match = description.match(/\\(([^:]+):/);\n if (match) {\n const field = match[1];\n // Additional filtering for common unwanted patterns\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return \"unknown\";\n }\n return field;\n }\n\n const fallbackMatch = description.match(/([a-zA-Z_]+):/);\n if (fallbackMatch) {\n const field = fallbackMatch[1];\n // Additional filtering for common unwanted patterns\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return \"unknown\";\n }\n return field;\n }\n\n return \"unknown\";\n}\n\nfunction mergeWeights(weights: ExplainParsedWeight[]): ExplainParsedWeight[] {\n const mergedWeights: Record<string, ExplainParsedWeight> = {};\n\n for (const weight of weights) {\n if (mergedWeights[weight.field]) {\n mergedWeights[weight.field].weight += weight.weight;\n } else {\n mergedWeights[weight.field] = { ...weight };\n }\n }\n\n return Object.values(mergedWeights);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"weight.js","sourceRoot":"","sources":["../../../src/utility/weight.ts"],"names":[],"mappings":"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","sourcesContent":["export type ExplainScoreDetail = {\n value: number;\n description: string;\n details?: ExplainScoreDetail[];\n};\n\nexport type ExplainParsedTerm = {\n term: string;\n weight: number;\n isSynonym: boolean;\n};\n\nexport type ExplainParsedWeight = {\n field: string;\n weight: number;\n terms: ExplainParsedTerm[];\n};\n\nexport function getWeight(explanation: ExplainScoreDetail): number {\n const detail = explanation.details?.find((detail) => detail.description === \"min of:\");\n return detail ? detail.value : explanation.value;\n}\n\nexport function explainWeight(explanation: ExplainScoreDetail): ExplainParsedWeight[] {\n const fieldWeights = parseWeights(explanation);\n const mergedWeights = mergeWeights(fieldWeights);\n const sortedWeights = mergedWeights.sort((a, b) => b.weight - a.weight);\n\n return sortedWeights;\n}\n\nfunction parseWeights(detail: ExplainScoreDetail): ExplainParsedWeight[] {\n const parsedWeights: ExplainParsedWeight[] = [];\n\n // Look for min_of score which contains the clean field weights\n if (detail.description.includes(\"min of:\")) {\n if (detail.details) {\n for (const subDetail of detail.details) {\n if (subDetail.description.includes(\"function score\") && subDetail.description.includes(\"product of:\")) {\n const parentWeight = subDetail.value;\n\n if (subDetail.details) {\n for (const functionDetail of subDetail.details) {\n if (functionDetail.description.includes(\"match filter:\")) {\n const fieldTermData = extractFieldWithTerm(functionDetail.description);\n if (fieldTermData) {\n parsedWeights.push({\n field: fieldTermData.field,\n weight: 0, // Will be calculated in mergeWeights\n terms: [{ term: fieldTermData.term, weight: parentWeight, isSynonym: fieldTermData.isSynonym }],\n });\n }\n }\n\n if (functionDetail.description.includes(\"weight\")) {\n const field = extractFieldNameFromDetails(functionDetail);\n if (field && field !== \"unknown\") {\n parsedWeights.push({\n field,\n weight: 0, // Will be calculated in mergeWeights\n terms: [{ term: \"unknown\", weight: parentWeight, isSynonym: false }],\n });\n }\n }\n }\n }\n }\n }\n }\n }\n\n // Fallback to original parsing if min_of is not found\n if (parsedWeights.length === 0) {\n if (detail.description.includes(\"function score\") && detail.description.includes(\"product of:\")) {\n const parentWeight = detail.value;\n\n if (detail.details) {\n for (const subDetail of detail.details) {\n if (subDetail.description.includes(\"match filter:\")) {\n const fieldTermData = extractFieldWithTerm(subDetail.description);\n if (fieldTermData) {\n parsedWeights.push({\n field: fieldTermData.field,\n weight: 0, // Will be calculated in mergeWeights\n terms: [{ term: fieldTermData.term, weight: parentWeight, isSynonym: fieldTermData.isSynonym }],\n });\n }\n }\n\n if (subDetail.description.includes(\"weight\")) {\n const field = extractFieldNameFromDetails(subDetail);\n if (field && field !== \"unknown\") {\n parsedWeights.push({\n field,\n weight: 0, // Will be calculated in mergeWeights\n terms: [{ term: \"unknown\", weight: parentWeight, isSynonym: false }],\n });\n }\n }\n }\n }\n }\n }\n\n if (detail.details) {\n for (const subDetail of detail.details) {\n parsedWeights.push(...parseWeights(subDetail));\n }\n }\n\n return parsedWeights;\n}\n\nfunction extractFieldFromMatchFilter(description: string): string | null {\n const lowerDescription = description.toLowerCase();\n\n // Filter out undesired values early\n if (\n lowerDescription.includes(\"freq\") ||\n lowerDescription.includes(\"perfieldsimilarity\") ||\n lowerDescription.includes(\"*:*\") ||\n lowerDescription.includes(\"_all\")\n ) {\n return null;\n }\n\n // Handle synonym queries: +Synonym(tags_colour:atlantic tags_colour:emerald ...) -tags_colour:green\n const synonymMatch = description.match(/\\+Synonym\\(([^:]+):/);\n if (synonymMatch) {\n const field = synonymMatch[1];\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return null;\n }\n return field;\n }\n\n // Handle simple match filters: match filter: title:shirt\n const simpleMatch = description.match(/match filter: ([a-zA-Z_]+):/);\n if (simpleMatch) {\n const field = simpleMatch[1];\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return null;\n }\n return field;\n }\n\n // Handle parenthesized match filters: match filter: (product_type:shirts)\n const parenthesizedMatch = description.match(/match filter: \\(([^:]+):/);\n if (parenthesizedMatch) {\n const field = parenthesizedMatch[1];\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return null;\n }\n return field;\n }\n\n // Handle complex queries with boosts: title:shirt (title:short)^0.8\n const complexMatch = description.match(/match filter: ([a-zA-Z_]+):[^(]+/);\n if (complexMatch) {\n const field = complexMatch[1];\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return null;\n }\n return field;\n }\n\n return null;\n}\n\nfunction extractTermFromFilter(description: string): { term: string; isSynonym: boolean } | null {\n // Extract from excluded terms in synonym queries: -field:term\n const excludedMatch = description.match(/-([a-zA-Z_]+):([^)\\s]+)/);\n if (excludedMatch) {\n const term = excludedMatch[2];\n if (term.includes(\"freq\") || term.includes(\"*\") || term.includes(\"_all\")) {\n return null;\n }\n return { term, isSynonym: true };\n }\n\n // Extract from direct matches: field:term (but not parenthesized synonyms)\n const directMatch = description.match(/match filter: ([a-zA-Z_]+):([^(\\s]+)/);\n if (directMatch) {\n const term = directMatch[2];\n if (term.includes(\"freq\") || term.includes(\"*\") || term.includes(\"_all\")) {\n return null;\n }\n return { term, isSynonym: false };\n }\n\n // Extract from parenthesized direct matches: (field:term)\n const parenthesizedMatch = description.match(/match filter: \\(([a-zA-Z_]+):([^)\\s]+)/);\n if (parenthesizedMatch) {\n const term = parenthesizedMatch[2];\n if (term.includes(\"freq\") || term.includes(\"*\") || term.includes(\"_all\")) {\n return null;\n }\n return { term, isSynonym: false };\n }\n\n return null;\n}\n\nfunction extractFieldWithTerm(description: string): { field: string; term: string; isSynonym: boolean } | null {\n const termData = extractTermFromFilter(description);\n if (!termData) return null;\n\n const fieldData = extractFieldFromMatchFilter(description);\n if (!fieldData) return null;\n\n return {\n field: fieldData,\n term: termData.term,\n isSynonym: termData.isSynonym,\n };\n}\n\nfunction extractFieldNameFromDetails(detail: ExplainScoreDetail): string {\n const description = detail.description.toLowerCase();\n\n // Filter out undesired values\n if (\n description.includes(\"freq\") ||\n description.includes(\"perfieldsimilarity\") ||\n description.includes(\"*:*\") ||\n description.includes(\"_all\")\n ) {\n return \"unknown\";\n }\n\n const match = description.match(/\\(([^:]+):/);\n if (match) {\n const field = match[1];\n // Additional filtering for common unwanted patterns\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return \"unknown\";\n }\n return field;\n }\n\n const fallbackMatch = description.match(/([a-zA-Z_]+):/);\n if (fallbackMatch) {\n const field = fallbackMatch[1];\n // Additional filtering for common unwanted patterns\n if (field.includes(\"freq\") || field.includes(\"*\") || field.includes(\"_all\")) {\n return \"unknown\";\n }\n return field;\n }\n\n return \"unknown\";\n}\n\nfunction mergeWeights(weights: ExplainParsedWeight[]): ExplainParsedWeight[] {\n const mergedWeights: Record<string, Record<string, ExplainParsedTerm>> = {};\n\n // Merge by field, then by term\n for (const weight of weights) {\n for (const term of weight.terms) {\n if (!mergedWeights[weight.field]) {\n mergedWeights[weight.field] = {};\n }\n\n if (mergedWeights[weight.field][term.term]) {\n mergedWeights[weight.field][term.term].weight += term.weight;\n } else {\n mergedWeights[weight.field][term.term] = { ...term };\n }\n }\n }\n\n // Convert back to array format and sort terms by weight\n const result: ExplainParsedWeight[] = [];\n for (const [field, terms] of Object.entries(mergedWeights)) {\n const termArray = Object.values(terms).sort((a, b) => b.weight - a.weight);\n const totalWeight = termArray.reduce((sum, term) => sum + term.weight, 0);\n result.push({ field, weight: totalWeight, terms: termArray });\n }\n\n return result;\n}\n\nexport function formatWeightBreakdown(weights: ExplainParsedWeight[]): string {\n return weights\n .sort((a, b) => b.weight - a.weight)\n .map((weight) => {\n const termBreakdown = weight.terms\n .map((term) => `${term.term}: ${term.weight.toFixed(2)}${term.isSynonym ? \" [synonym]\" : \"\"}`)\n .join(\", \");\n return `${weight.field}: ${weight.weight.toFixed(2)} (${termBreakdown})`;\n })\n .join(\"\\n\");\n}\n"]}
|