Browse Source

Hotfix for confidence exception

pull/299/head
Diana Shkolnikov 9 years ago
parent
commit
ce32802368
  1. 37
      middleware/confidenceScore.js
  2. 82
      test/unit/middleware/confidenceScore.js
  3. 1
      test/unit/run.js

37
middleware/confidenceScore.js

@ -13,17 +13,21 @@
var stats = require('stats-lite');
var logger = require('pelias-logger').get('api');
var check = require('check-types');
var RELATIVE_SCORES = true;
function setup(peliasConfig) {
RELATIVE_SCORES = peliasConfig.hasOwnProperty('relativeScores') ? peliasConfig.relativeScores : true;
if (check.assigned(peliasConfig)) {
RELATIVE_SCORES = peliasConfig.hasOwnProperty('relativeScores') ? peliasConfig.relativeScores : true;
}
return computeScores;
}
function computeScores(req, res, next) {
// do nothing if no result data set
if (!res || !res.data || !res.meta) {
if (check.undefined(req.clean) || check.undefined(res) ||
check.undefined(res.data) || check.undefined(res.meta)) {
return next();
}
@ -71,6 +75,7 @@ function computeConfidenceScore(req, mean, stdev, hit) {
// TODO: look at categories and location
hit.confidence /= checkCount;
hit.confidence = Number((hit.confidence).toFixed(3));
logger.debug('[confidence]:', hit.confidence, hit.name.default);
@ -78,16 +83,16 @@ function computeConfidenceScore(req, mean, stdev, hit) {
}
function checkForDealBreakers(req, hit) {
if (!req.clean.parsed_text) {
if (check.undefined(req.clean.parsed_text)) {
return false;
}
if (req.clean.parsed_text.state && req.clean.parsed_text.state !== hit.admin1_abbr) {
if (check.assigned(req.clean.parsed_text.state) && req.clean.parsed_text.state !== hit.admin1_abbr) {
logger.debug('[confidence][deal-breaker]: state !== admin1_abbr');
return true;
}
if (req.clean.parsed_text.postalcode && req.clean.parsed_text.postalcode !== hit.zip) {
if (check.assigned(req.clean.parsed_text.postalcode) && req.clean.parsed_text.postalcode !== hit.zip) {
logger.debug('[confidence][deal-breaker]: postalcode !== zip');
return true;
}
@ -117,7 +122,8 @@ function checkDistanceFromMean(score, mean, stdev) {
*/
function checkName(text, parsed_text, hit) {
// parsed_text name should take precedence if available since it's the cleaner name property
if (parsed_text && parsed_text.name && hit.name.default.toLowerCase() === parsed_text.name.toLowerCase()) {
if (check.assigned(parsed_text) && check.assigned(parsed_text.name) &&
hit.name.default.toLowerCase() === parsed_text.name.toLowerCase()) {
return 1;
}
@ -139,7 +145,9 @@ function checkName(text, parsed_text, hit) {
* @returns {number}
*/
function checkQueryType(text, hit) {
if (!!text.number && (!hit.address || (hit.address && !hit.address.number))) {
if (check.assigned(text) && check.assigned(text.number) &&
(check.undefined(hit.address) ||
(check.assigned(hit.address) && check.undefined(hit.address.number)))) {
return 0;
}
return 1;
@ -156,22 +164,23 @@ function checkQueryType(text, hit) {
function propMatch(textProp, hitProp, expectEnriched) {
// both missing, but expect to have enriched value in result => BAD
if (!textProp && !hitProp && expectEnriched) { return 0; }
if (check.undefined(textProp) && check.undefined(hitProp) && check.assigned(expectEnriched)) { return 0; }
// both missing, and no enrichment expected => GOOD
if (!textProp && !hitProp) { return 1; }
if (check.undefined(textProp) && check.undefined(hitProp)) { return 1; }
// text has it, result doesn't => BAD
if (textProp && !hitProp) { return 0; }
if (check.assigned(textProp) && check.undefined(hitProp)) { return 0; }
// text missing, result has it, and enrichment is expected => GOOD
if (!textProp && hitProp && expectEnriched) { return 1; }
if (check.undefined(textProp) && check.assigned(hitProp) && check.assigned(expectEnriched)) { return 1; }
// text missing, result has it, enrichment not desired => 50/50
if (!textProp && hitProp) { return 0.5; }
if (check.undefined(textProp) && check.assigned(hitProp)) { return 0.5; }
// both present, values match => GREAT
if (textProp && hitProp && textProp.toString().toLowerCase() === hitProp.toString().toLowerCase()) { return 1; }
if (check.assigned(textProp) && check.assigned(hitProp) &&
textProp.toString().toLowerCase() === hitProp.toString().toLowerCase()) { return 1; }
// ¯\_(ツ)_/¯
return 0.7;
@ -200,7 +209,7 @@ function checkAddress(text, hit) {
var checkCount = 5;
var res = 0;
if (text && text.number && text.street) {
if (check.assigned(text) && check.assigned(text.number) && check.assigned(text.street)) {
res += propMatch(text.number, (hit.address ? hit.address.number : null), false);
res += propMatch(text.street, (hit.address ? hit.address.street : null), false);
res += propMatch(text.postalcode, (hit.address ? hit.address.zip: null), true);

82
test/unit/middleware/confidenceScore.js

@ -0,0 +1,82 @@
var confidenceScore = require('../../../middleware/confidenceScore')();
module.exports.tests = {};
module.exports.tests.confidenceScore = function(test, common) {
test('empty res and req should not throw exception', function(t) {
try {
confidenceScore({}, {}, function() {});
t.pass('no exception');
}
catch (e) {
t.fail('an exception should not have been thrown');
}
finally {
t.end();
}
});
test('res.results without parsed_text should not throw exception', function(t) {
var req = {};
var res = {
data: [{
name: 'foo'
}],
meta: [10]
};
try {
confidenceScore(req, res, function() {});
t.pass('no exception');
}
catch (e) {
t.fail('an exception should not have been thrown');
console.log(e.stack);
}
finally {
t.end();
}
});
test('res.results without parsed_text should not throw exception', function(t) {
var req = {
clean: { text: 'test name1' }
};
var res = {
data: [{
_score: 10,
found: true,
value: 1,
center_point: { lat: 100.1, lon: -50.5 },
name: { default: 'test name1' },
admin0: 'country1', admin1: 'state1', admin2: 'city1'
}, {
value: 2,
center_point: { lat: 100.2, lon: -51.5 },
name: { default: 'test name2' },
admin0: 'country2', admin1: 'state2', admin2: 'city2',
_score: 20
}],
meta: {scores: [10]}
};
confidenceScore(req, res, function() {});
t.equal(res.data[0].confidence, 0.6, 'score was set');
t.end();
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('[middleware] confidenceScore: ' + name, testFunction);
}
for( var testCase in module.exports.tests ){
module.exports.tests[testCase](test, common);
}
};

1
test/unit/run.js

@ -29,6 +29,7 @@ var tests = [
require('./sanitiser/_geo_common'),
require('./middleware/distance'),
require('./middleware/confidenceScoreReverse'),
require('./middleware/confidenceScore'),
require('./sanitiser/_size'),
require('./sanitiser/_single_scalar_parameters'),
require('./sanitiser/_geo_reverse'),

Loading…
Cancel
Save