Browse Source

feat(max_character_count_layer_filter): filter layer=address records for character counts <= 2

max_character_count_layer_filter
Peter Johnson 6 years ago
parent
commit
b2f90623b6
  1. 12
      query/autocomplete.js
  2. 47
      query/view/max_character_count_layer_filter.js
  3. 117
      test/unit/query/view/max_character_count_layer_filter.js
  4. 1
      test/unit/run.js

12
query/autocomplete.js

@ -6,11 +6,12 @@ const logger = require('pelias-logger').get('api');
// additional views (these may be merged in to pelias/query at a later date)
var views = {
ngrams_strict: require('./view/ngrams_strict'),
ngrams_last_token_only: require('./view/ngrams_last_token_only'),
phrase_first_tokens_only: require('./view/phrase_first_tokens_only'),
pop_subquery: require('./view/pop_subquery'),
boost_exact_matches: require('./view/boost_exact_matches')
ngrams_strict: require('./view/ngrams_strict'),
ngrams_last_token_only: require('./view/ngrams_last_token_only'),
phrase_first_tokens_only: require('./view/phrase_first_tokens_only'),
pop_subquery: require('./view/pop_subquery'),
boost_exact_matches: require('./view/boost_exact_matches'),
max_character_count_layer_filter: require('./view/max_character_count_layer_filter')
};
//------------------------------
@ -45,6 +46,7 @@ query.score( peliasQuery.view.popularity( views.pop_subquery ) );
query.score( peliasQuery.view.population( views.pop_subquery ) );
// non-scoring hard filters
query.score( views.max_character_count_layer_filter('address', 2), 'must_not' );
query.filter( peliasQuery.view.sources );
query.filter( peliasQuery.view.layers );
query.filter( peliasQuery.view.boundary_rect );

47
query/view/max_character_count_layer_filter.js

@ -0,0 +1,47 @@
const _ = require('lodash');
const peliasQuery = require('pelias-query');
/**
Layer terms filter view which counts the length of 'input:name' and only
applies the filter condition if the text is shorter than or equal to $maxCharCount.
eg. to filter by 'layer=address' for all one & two digit inputs:
view = filter('address',2)
**/
// lowest and highest valid character count (enforced)
const MIN_CHAR_COUNT = 1;
const MAX_CHAR_COUNT = 99;
module.exports = function( layerName, maxCharCount ) {
// validate args, return no-op view if invalid
if( !_.isString(layerName) || _.isEmpty(layerName) ||
!_.isNumber(maxCharCount) ){
return () => null;
}
// ensure char count is within a reasonable range
maxCharCount = _.clamp(maxCharCount, MIN_CHAR_COUNT, MAX_CHAR_COUNT);
return function( vs ){
// validate required params
if( !vs.isset('input:name') ){
return null;
}
// enforce maximum character length
let charCount = vs.var('input:name').toString().length;
if( !_.inRange(charCount, 1, maxCharCount+1) ){
return null;
}
return {
terms: {
layer: layerName
}
};
};
};

117
test/unit/query/view/max_character_count_layer_filter.js

@ -0,0 +1,117 @@
const VariableStore = require('pelias-query').Vars;
const maxCharFilter = require('../../../../query/view/max_character_count_layer_filter');
module.exports.tests = {};
module.exports.tests.interface = function(test, common) {
test('interface: factory', function(t) {
t.equal(typeof maxCharFilter, 'function', 'valid factory function');
t.equal(maxCharFilter.length, 2, 'factory takes 2 args');
t.end();
});
test('interface: view', function(t) {
let view = maxCharFilter('layer_name', 1);
t.equal(typeof view, 'function', 'returns view');
t.equal(view.length, 1, 'view takes 1 arg');
t.end();
});
};
module.exports.tests.factory_missing_required_args = function(test, common) {
test('layerName undefined', function(t) {
let view = maxCharFilter(undefined, 1);
t.equal(view(), null, 'should have returned null');
t.end();
});
test('layerName not string', function(t) {
let view = maxCharFilter([], 1);
t.equal(view(), null, 'should have returned null');
t.end();
});
test('layerName too short', function(t) {
let view = maxCharFilter('', 1);
t.equal(view(), null, 'should have returned null');
t.end();
});
test('maxCharCount undefined', function(t) {
let view = maxCharFilter('layer_name', undefined);
t.equal(view(), null, 'should have returned null');
t.end();
});
test('maxCharCount not number', function(t) {
let view = maxCharFilter('layer_name', '1');
t.equal(view(), null, 'should have returned null');
t.end();
});
};
module.exports.tests.view_missing_required_params = function(test, common) {
test('input:name not set in VariableStore should return null', function(t) {
let view = maxCharFilter('layer_name', 1);
let vs = new VariableStore();
t.equal(view(vs), null, 'should have returned null');
t.end();
});
};
module.exports.tests.view_within_range = function(test, common) {
test('text length within range', function(t) {
let view = maxCharFilter('layer_name', 99);
let vs = new VariableStore();
vs.var('input:name', 'example text');
let actual = view(vs);
let expected = {
terms: {
layer: 'layer_name'
}
};
t.deepEquals(actual, expected, 'should have returned object');
t.end();
});
};
module.exports.tests.view_exceeds_range = function(test, common) {
test('text length exceeds range', function(t) {
let view = maxCharFilter('layer_name', 11);
let vs = new VariableStore();
vs.var('input:name', 'example text');
t.equal(view(vs), null, 'should have returned null');
t.end();
});
};
module.exports.tests.view_clamp_range_low = function(test, common) {
test('maxCharCount less than one is equal to one', function(t) {
let view = maxCharFilter('layer_name', -999);
let vs = new VariableStore();
vs.var('input:name', 'ex');
t.equal(view(vs), null, 'should have returned null');
t.end();
});
test('maxCharCount less than one is equal to one', function(t) {
let view = maxCharFilter('layer_name', -999);
let vs = new VariableStore();
vs.var('input:name', 'e');
let actual = view(vs);
let expected = {
terms: {
layer: 'layer_name'
}
};
t.deepEquals(actual, expected, 'should have returned object');
t.end();
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('filter ' + name, testFunction);
}
for( let testCase in module.exports.tests ){
module.exports.tests[testCase](test, common);
}
};

1
test/unit/run.js

@ -71,6 +71,7 @@ var tests = [
require('./query/search_original'),
require('./query/structured_geocoding'),
require('./query/text_parser'),
require('./query/view/max_character_count_layer_filter'),
require('./sanitizer/_boundary_country'),
require('./sanitizer/_debug'),
require('./sanitizer/_flag_bool'),

Loading…
Cancel
Save