feat: add boosting to context based search

This commit is contained in:
Michel Jonathan Schmitz
2019-04-16 15:29:13 +02:00
committed by Rainer Killinger
parent 67c814443c
commit dd4be92f90
4 changed files with 268 additions and 661 deletions

View File

@@ -178,7 +178,8 @@ const config: Partial<SCConfigFile> = {
fieldName: 'type', fieldName: 'type',
}, },
], ],
boostings: [ boostings: {
default: [
{ {
factor: 1, factor: 1,
fields: { fields: {
@@ -186,7 +187,7 @@ const config: Partial<SCConfigFile> = {
'SS 2018': 1.05, 'SS 2018': 1.05,
'WS 2018/19': 1.1, 'WS 2018/19': 1.1,
}, },
categories: { 'categories': {
'course': 1.08, 'course': 1.08,
'integrated course': 1.08, 'integrated course': 1.08,
'introductory class': 1.05, 'introductory class': 1.05,
@@ -223,6 +224,40 @@ const config: Partial<SCConfigFile> = {
type: SCThingType.Dish, type: SCThingType.Dish,
}, },
], ],
place: [
{
factor: 2,
type: SCThingType.Building,
},
{
factor: 2,
type: SCThingType.PointOfInterest,
},
{
factor: 2,
type: SCThingType.Room,
},
],
dining: [
{
factor: 1,
fields: {
'categories': {
'cafe': 2,
'restaurant': 2,
'canteen': 2,
'student canteen': 2,
'restroom': 1.2,
},
},
type: SCThingType.Building,
},
{
factor: 2,
type: SCThingType.Dish,
},
],
},
}, },
uid: 'b-tu', uid: 'b-tu',
}; };

763
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,16 +12,17 @@
], ],
"scripts": { "scripts": {
"build": "npm run tslint && npm run compile", "build": "npm run tslint && npm run compile",
"compile": "rimraf lib && tsc --outDir lib && prepend lib/cli.js '#!/usr/bin/env node\n'", "compile": "rimraf lib && tsc && prepend lib/cli.js '#!/usr/bin/env node\n'",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
"check-configuration": "openstapps-configuration", "check-configuration": "openstapps-configuration",
"documentation": "typedoc --includeDeclarations --excludeExternals --mode modules --out docs src", "documentation": "typedoc --includeDeclarations --mode modules --out docs --readme README.md --listInvalidSymbolLinks src",
"prepublishOnly": "npm ci && npm run build",
"start": "NODE_CONFIG_ENV=elasticsearch ALLOW_NO_TRANSPORT=true node ./lib/cli.js", "start": "NODE_CONFIG_ENV=elasticsearch ALLOW_NO_TRANSPORT=true node ./lib/cli.js",
"tslint": "tslint 'src/**/*.ts'" "tslint": "tslint 'src/**/*.ts'"
}, },
"dependencies": { "dependencies": {
"@openstapps/core": "0.12.0", "@openstapps/core": "0.15.0",
"@openstapps/core-tools": "0.3.0", "@openstapps/core-tools": "0.5.1",
"@openstapps/logger": "0.0.5", "@openstapps/logger": "0.0.5",
"config": "3.0.1", "config": "3.0.1",
"cors": "2.8.5", "cors": "2.8.5",
@@ -42,7 +43,7 @@
"uuid": "3.3.2" "uuid": "3.3.2"
}, },
"devDependencies": { "devDependencies": {
"@openstapps/configuration": "0.6.0", "@openstapps/configuration": "0.8.0",
"@types/config": "0.0.34", "@types/config": "0.0.34",
"@types/cors": "2.8.4", "@types/cors": "2.8.4",
"@types/elasticsearch": "5.0.31", "@types/elasticsearch": "5.0.31",
@@ -61,6 +62,6 @@
"prepend-file-cli": "1.0.6", "prepend-file-cli": "1.0.6",
"rimraf": "2.6.3", "rimraf": "2.6.3",
"typedoc": "0.14.2", "typedoc": "0.14.2",
"typescript": "3.3.3333" "typescript": "3.3.4000"
} }
} }

View File

@@ -14,9 +14,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { import {
SCBackendConfigurationSearchBoosting, SCBackendConfigurationSearchBoostingContext,
SCBackendConfigurationSearchBoostingType,
SCConfigFile, SCConfigFile,
SCSearchBooleanFilter, SCSearchBooleanFilter,
SCSearchContext,
SCSearchFilter, SCSearchFilter,
SCSearchQuery, SCSearchQuery,
SCSearchSort, SCSearchSort,
@@ -147,15 +149,37 @@ export function buildFilter(filter: SCSearchFilter): ESTermFilter | ESGeoDistanc
/** /**
* Builds scorings functions from boosting config * Builds scorings functions from boosting config
* @param boosting * @param boostings Backend boosting configuration for contexts and types
* @returns * @param context The context of the app from where the search was initiated
*/ */
export function buildFunctions(boosting: SCBackendConfigurationSearchBoosting[]): ESFunctionScoreQueryFunction[] { function buildFunctions(
boostings: SCBackendConfigurationSearchBoostingContext,
context: SCSearchContext | undefined,
): ESFunctionScoreQueryFunction[] {
// default context
let functions: ESFunctionScoreQueryFunction[] =
buildFunctionsForBoostingTypes(boostings['default' as SCSearchContext]);
if (typeof context !== 'undefined' && context !== 'default') {
// specific context provided, extend default context with additional boosts
functions = functions.concat(buildFunctionsForBoostingTypes(boostings[context]));
}
return functions;
}
/**
* Creates boost functions for all type boost configurations
*
* @param boostingTypes Array of type boosting configurations
*/
function buildFunctionsForBoostingTypes(
boostingTypes: SCBackendConfigurationSearchBoostingType[],
): ESFunctionScoreQueryFunction[] {
const functions: ESFunctionScoreQueryFunction[] = []; const functions: ESFunctionScoreQueryFunction[] = [];
// add a good scoring subset from config file boostingTypes.forEach((boostingForOneSCType) => {
boosting.forEach((boostingForOneSCType) => {
const typeFilter: ESTypeFilter = { const typeFilter: ESTypeFilter = {
type: { type: {
value: boostingForOneSCType.type, value: boostingForOneSCType.type,
@@ -305,7 +329,7 @@ export function buildQuery(
const functionScoreQuery: ESFunctionScoreQuery = { const functionScoreQuery: ESFunctionScoreQuery = {
function_score: { function_score: {
functions: buildFunctions(defaultConfig.internal.boostings), functions: buildFunctions(defaultConfig.internal.boostings, params.context),
query: { query: {
bool: { bool: {
minimum_should_match: 0, // if we have no should, nothing can match minimum_should_match: 0, // if we have no should, nothing can match