coveo-search-ui
Version:
Coveo JavaScript Search Framework
185 lines (160 loc) • 5.2 kB
text/typescript
import { object, map, keys, reduce } from 'underscore';
import { StringUtils } from '../../utils/StringUtils';
import { $$, Dom } from '../../utils/Dom';
export interface IRankingInfo {
documentWeights: IListOfWeights;
totalWeight: number;
termsWeight: IListOfTermsWeights;
qreWeights: IListOfQRE[];
}
export interface IListOfWeights {
Adjacency: number;
'Collaborative rating': number;
Custom: number;
Date: number;
QRE: number;
Quality: number;
'Ranking functions': number;
Source: number;
Title: number;
[key: string]: number;
}
export interface IListOfQRE {
expression: string;
score: number;
}
export type IListOfTermsWeights = Record<string, IWeightsPerTerm>;
export interface IWeightsPerTerm {
Weights: IWeightsPerTermBreakdown;
terms: Record<string, IWeightsPerTermPerDocument>;
}
export interface IWeightsPerTermBreakdown {
Casing: number;
Concept: number;
Formatted: number;
Frequency: number;
Relation: number;
Summary: number;
Title: number;
URI: number;
[key: string]: number;
}
export interface IWeightsPerTermPerDocument {
Correlation: number;
'TF-IDF': number;
}
export const buildListOfTermsElement = (weightPerTerm: IWeightsPerTermBreakdown): Dom => {
const listItems = map(weightPerTerm, (value, key) => {
return {
dt: $$(
'dt',
{
className: 'coveo-relevance-inspector-dt'
},
`${key}`
),
dd: $$(
'dd',
{
className: 'coveo-relevance-inspector-dd'
},
`${value}`
)
};
});
const total = reduce(weightPerTerm, (memo, value) => memo + value, 0);
const list = $$('dl');
listItems.forEach(item => {
list.append(item.dt.el);
list.append(item.dd.el);
});
list.append($$('dt', { className: 'coveo-relevance-inspector-dt' }, `Total`).el);
list.append($$('dd', { className: 'coveo-relevance-inspector-dd coveo-relevance-inspector-highlight' }, `${total}`).el);
return list;
};
export const parseRankingInfo = (value: string): IRankingInfo | null => {
const REGEX_EXTRACT_DOCUMENT_WEIGHTS = /Document weights:\n((?:.)*?)\n+/g;
const REGEX_EXTRACT_TERMS_WEIGHTS = /Terms weights:\n((?:.|\n)*)\n+/g;
const REGEX_EXTRACT_TOTAL_WEIGHTS = /Total weight: ([0-9]+)/g;
if (value) {
const docWeightsRegexResult = REGEX_EXTRACT_DOCUMENT_WEIGHTS.exec(value);
const termsWeightRegexResult = REGEX_EXTRACT_TERMS_WEIGHTS.exec(value);
const totalWeigthRegexResult = REGEX_EXTRACT_TOTAL_WEIGHTS.exec(value);
const qreWeights = parseQREWeights(value);
const documentWeights = parseWeights(docWeightsRegexResult ? docWeightsRegexResult[1] : null);
const termsWeight = parseTermsWeights(termsWeightRegexResult);
const totalWeight = totalWeigthRegexResult ? Number(totalWeigthRegexResult[1]) : null;
return {
documentWeights,
termsWeight,
totalWeight,
qreWeights
};
}
return null;
};
const parseWeights = (value: string | null): IListOfWeights | null => {
const REGEX_EXTRACT_LIST_OF_WEIGHTS = /(\w+(?:\s\w+)*): ([-0-9]+)/g;
const REGEX_EXTRACT_WEIGHT_GROUP = /^(\w+(?:\s\w+)*): ([-0-9]+)$/;
if (value) {
const listOfWeight = value.match(REGEX_EXTRACT_LIST_OF_WEIGHTS);
if (listOfWeight) {
return object(
listOfWeight.map(weight => {
let weightGroup = weight.match(REGEX_EXTRACT_WEIGHT_GROUP);
if (weightGroup) {
const weightAppliedOn = weightGroup[1];
const weightValue = weightGroup[2];
return [weightAppliedOn, Number(weightValue)];
}
return null;
})
) as IListOfWeights;
}
}
return null;
};
const parseTermsWeights = (termsWeight: RegExpExecArray | null): IListOfTermsWeights | null => {
const REGEX_EXTRACT_GROUP_OF_TERMS = /((?:[^:]+: [0-9]+, [0-9]+; )+)\n((?:\w+: [0-9]+; )+)/g;
const REGEX_EXTRACT_SINGLE_TERM = /([^:]+): ([0-9]+), ([0-9]+); /g;
if (termsWeight && termsWeight[1]) {
let terms = StringUtils.match(termsWeight[1], REGEX_EXTRACT_GROUP_OF_TERMS);
return object(
map(terms, term => {
let words = object(
map(StringUtils.match(term[1], REGEX_EXTRACT_SINGLE_TERM), word => {
return [
word[1],
{
Correlation: Number(word[2]),
'TF-IDF': Number(word[3])
}
];
})
);
const weights = parseWeights(term[2]);
return [
keys(words).join(', '),
{
terms: words,
Weights: weights
}
];
})
) as IListOfTermsWeights;
}
return null;
};
const parseQREWeights = (value: string): IListOfQRE[] => {
const REGEX_EXTRACT_QRE_WEIGHTS = /(Expression:\s".*")\sScore:\s(?!0)([-0-9]+)\n+/g;
let qreWeightsRegexResult = REGEX_EXTRACT_QRE_WEIGHTS.exec(value);
const qreWeights: IListOfQRE[] = [];
while (qreWeightsRegexResult) {
qreWeights.push({
expression: qreWeightsRegexResult[1],
score: parseInt(qreWeightsRegexResult[2], 10)
});
qreWeightsRegexResult = REGEX_EXTRACT_QRE_WEIGHTS.exec(value);
}
return qreWeights;
};