Browse Source

feat(query): Add support for custom boosts to search endpoint

This adds support for custom boosts to the addressit-style search
queries. The newer libpostal based queries do not include this
functionality since they can only query for addresses.
cb_sorting
Julian Simioni 6 years ago
parent
commit
c4428a159a
No known key found for this signature in database
GPG Key ID: B9EEB0C6EE0910A1
  1. 7
      query/search_original.js
  2. 107
      test/unit/fixture/search_with_custom_boosts.json
  3. 55
      test/unit/query/search_with_custom_boosts.js
  4. 1
      test/unit/run.js

7
query/search_original.js

@ -3,9 +3,13 @@ const defaults = require('./search_defaults');
const textParser = require('./text_parser_addressit'); const textParser = require('./text_parser_addressit');
const check = require('check-types'); const check = require('check-types');
const logger = require('pelias-logger').get('api'); const logger = require('pelias-logger').get('api');
const config = require('pelias-config').generate().api;
var placeTypes = require('../helper/placeTypes'); var placeTypes = require('../helper/placeTypes');
var views = {
custom_boosts: require('./view/boost_sources_and_layers'),
};
// region_a is also an admin field. addressit tries to detect // region_a is also an admin field. addressit tries to detect
// region_a, in which case we use a match query specifically for it. // region_a, in which case we use a match query specifically for it.
// but address it doesn't know about all of them so it helps to search // but address it doesn't know about all of them so it helps to search
@ -40,6 +44,9 @@ query.score( peliasQuery.view.admin('country_a') );
query.score( peliasQuery.view.admin('region_a') ); query.score( peliasQuery.view.admin('region_a') );
query.score( peliasQuery.view.admin_multi_match(adminFields, 'peliasAdmin') ); query.score( peliasQuery.view.admin_multi_match(adminFields, 'peliasAdmin') );
const boostConfig = config.customBoosts || {};
query.score( views.custom_boosts(config.customBoosts) );
// non-scoring hard filters // non-scoring hard filters
query.filter( peliasQuery.view.boundary_circle ); query.filter( peliasQuery.view.boundary_circle );
query.filter( peliasQuery.view.boundary_rect ); query.filter( peliasQuery.view.boundary_rect );

107
test/unit/fixture/search_with_custom_boosts.json

@ -0,0 +1,107 @@
{
"type": "original",
"body": {
"query": {
"bool": {
"must": [{
"match": {
"name.default": {
"query": "test",
"boost": 1,
"analyzer": "peliasQueryFullToken"
}
}
}],
"should": [{
"match": {
"phrase.default": {
"query": "test",
"analyzer": "peliasPhrase",
"type": "phrase",
"boost": 1,
"slop": 2
}
}
},{
"function_score": {
"query": {
"match": {
"phrase.default": {
"query": "test",
"analyzer": "peliasPhrase",
"type": "phrase",
"slop": 2,
"boost": 1
}
}
},
"max_boost": 20,
"score_mode": "first",
"boost_mode": "replace",
"functions": [{
"field_value_factor": {
"modifier": "log1p",
"field": "popularity",
"missing": 1
},
"weight": 1
}]
}
},{
"function_score": {
"query": {
"match": {
"phrase.default": {
"query": "test",
"analyzer": "peliasPhrase",
"type": "phrase",
"slop": 2,
"boost": 1
}
}
},
"max_boost": 20,
"score_mode": "first",
"boost_mode": "replace",
"functions": [{
"field_value_factor": {
"modifier": "log1p",
"field": "population",
"missing": 1
},
"weight": 2
}]
}
}, {
"bool": {
"should": [
{
"constant_score": {
"boost": 5,
"query": {
"term": {
"source": "openstreetmap"
}
}
}
},
{
"constant_score": {
"boost": 3,
"query": {
"term": {
"layer": "transit"
}
}
}
}
]
}
}]
}
},
"sort": [ "_score" ],
"size": 10,
"track_scores": true
}
}

55
test/unit/query/search_with_custom_boosts.js

@ -0,0 +1,55 @@
const proxyquire = require('proxyquire');
module.exports.tests = {};
module.exports.tests.query = function(test, common) {
test('valid search with custom boosts', function(t) {
const clean = {
tokens: ['foo'],
tokens_complete: ['foo'],
tokens_incomplete: [],
text: 'test',
querySize: 10
};
const config_with_boosts = {
generate: function() {
return {
api: {
customBoosts: {
source: {
openstreetmap: 5
},
layer: {
transit: 3
}
}
}
};
}
};
var expected_query = require('../fixture/search_with_custom_boosts.json');
const search_query_module = proxyquire('../../../query/search_original', {
'pelias-config': config_with_boosts
});
const actual_query = JSON.parse( JSON.stringify( search_query_module(clean) ) );
console.log(JSON.stringify(actual_query.body.query.bool, null, 2));
t.deepEqual(actual_query, expected_query, 'query as expected');
t.pass();
t.end();
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('search with custom boosts query ' + name, testFunction);
}
for( var testCase in module.exports.tests ){
module.exports.tests[testCase](test, common);
}
};

1
test/unit/run.js

@ -68,6 +68,7 @@ var tests = [
require('./query/reverse'), require('./query/reverse'),
require('./query/reverse_defaults'), require('./query/reverse_defaults'),
require('./query/search'), require('./query/search'),
require('./query/search_with_custom_boosts'),
require('./query/search_defaults'), require('./query/search_defaults'),
require('./query/search_original'), require('./query/search_original'),
require('./query/structured_geocoding'), require('./query/structured_geocoding'),

Loading…
Cancel
Save