|
|
|
/**
|
|
|
|
This view allows users to specify a custom boost for sources and layers.
|
|
|
|
|
|
|
|
The view is implemented using a 'function_score' query, which enumerates multiple 'functions', each
|
|
|
|
function will assign a 'score' to each document when matched.
|
|
|
|
|
|
|
|
A document can match more than one function, in this case the 'score_mode' is used to decide how these
|
|
|
|
scores are combined, the default is 'sum'.
|
|
|
|
|
|
|
|
Likewise, a document can also match zero functions, in this case it is assigned a score of 'min_score'.
|
|
|
|
|
|
|
|
The computed score is then multiplied by the 'boost' value in order to come up with the final boost value
|
|
|
|
which will be assigned to that document. The 'boost' value is essentially a hard-coded multiplier for the score.
|
|
|
|
|
|
|
|
The 'max_boost' property is simply a ceiling for this computed boost, if the computed boosted is higher than
|
|
|
|
max_boost it will be assigned the value of max_boost instead.
|
|
|
|
|
|
|
|
Note: This is a simple use of the 'function_score' query, as such we don't use the 'boost_mode' property
|
|
|
|
(because there is no query section) and the 'weight' values we assign are simply returned verbatim
|
|
|
|
(because we use filter queries for the function scoring).
|
|
|
|
|
|
|
|
ref: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html
|
|
|
|
|
|
|
|
example config section:
|
|
|
|
{
|
|
|
|
"source": {
|
|
|
|
"openstreetmap": 5
|
|
|
|
},
|
|
|
|
"layer": {
|
|
|
|
"street": 3,
|
|
|
|
"country": 5
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
example query:
|
|
|
|
{
|
|
|
|
"function_score": {
|
|
|
|
"query": {
|
|
|
|
"match_all": {}
|
|
|
|
},
|
|
|
|
"functions": [{
|
|
|
|
"filter": {
|
|
|
|
"match": {
|
|
|
|
"layer": "intersections"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"weight": 1.6
|
|
|
|
},{
|
|
|
|
"filter": {
|
|
|
|
"match": {
|
|
|
|
"layer": "stops"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"weight": 2.4
|
|
|
|
}],
|
|
|
|
"boost": 5,
|
|
|
|
"max_boost": 40,
|
|
|
|
"score_mode": "sum",
|
|
|
|
"boost_mode": "multiply",
|
|
|
|
"min_score": 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
**/
|
|
|
|
|
|
|
|
// supported top-level config items
|
|
|
|
const TARGETS = ['source', 'layer'];
|
|
|
|
|
|
|
|
module.exports = function( config ) {
|
|
|
|
|
|
|
|
// no valid config to use, fail now, don't render this view.
|
|
|
|
if( !config ) { return function(){ return null; }; }
|
|
|
|
|
|
|
|
return function( vs ) {
|
|
|
|
|
|
|
|
// validate required params
|
|
|
|
if( !vs.isset('custom:boosting:min_score') ||
|
|
|
|
!vs.isset('custom:boosting:boost') ||
|
|
|
|
!vs.isset('custom:boosting:max_boost') ||
|
|
|
|
!vs.isset('custom:boosting:score_mode') ||
|
|
|
|
!vs.isset('custom:boosting:boost_mode') ){
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// base 'function_score' view
|
|
|
|
var view = {
|
|
|
|
'function_score': {
|
|
|
|
'query': { 'match_all': {} }, // apply to all documents
|
|
|
|
'functions': [], // a list of functions which contribute to a 'score' for each document
|
|
|
|
'min_score': vs.var('custom:boosting:min_score'),
|
|
|
|
'boost': vs.var('custom:boosting:boost'),
|
|
|
|
'max_boost': vs.var('custom:boosting:max_boost'),
|
|
|
|
'score_mode': vs.var('custom:boosting:score_mode'),
|
|
|
|
'boost_mode': vs.var('custom:boosting:boost_mode')
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
// iterate over supported targets and their values
|
|
|
|
TARGETS.forEach( function( target ) {
|
|
|
|
if( 'object' === typeof config[target] ) {
|
|
|
|
Object.keys(config[target]).forEach(function(value) {
|
|
|
|
|
|
|
|
// add a scoring function for this target, assigning a weight
|
|
|
|
let weight = config[target][value];
|
|
|
|
view.function_score.functions.push({
|
|
|
|
'weight': isNaN(weight) ? 1 : weight,
|
|
|
|
'filter': {
|
|
|
|
'match': {
|
|
|
|
[target]: value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// no functions were generated, fail now, don't render this view.
|
|
|
|
if( view.function_score.functions.length === 0 ) { return null; }
|
|
|
|
|
|
|
|
return view;
|
|
|
|
};
|
|
|
|
};
|