Skip to content

Commit bcca87e

Browse files
committed
feat(assignLabels): improve duplicate label handling
1 parent 0f638f1 commit bcca87e

File tree

3 files changed

+51
-8
lines changed

3 files changed

+51
-8
lines changed

middleware/assignLabels.js

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
const defaultLabelGenerator = require('pelias-labels');
1+
const defaultLabelGenerator = require('pelias-labels').partsGenerator;
2+
const _ = require('lodash');
23

34
function setup(labelGenerator) {
45
function middleware(req, res, next) {
@@ -8,17 +9,55 @@ function setup(labelGenerator) {
89
return middleware;
910
}
1011

12+
function getLabelFromLayer(parts, layer) {
13+
const part = parts.find(p => p.layer === layer);
14+
return _.get(part, 'label');
15+
}
16+
17+
function filterUnambiguousParts(part, second) {
18+
if (part.role === 'required') {
19+
return false;
20+
}
21+
const label = getLabelFromLayer(second.parts, part.layer);
22+
return label && label !== part.label;
23+
}
24+
25+
function getBestLayers(results) {
26+
const first = results[0];
27+
const second = results[1];
28+
return first.parts.filter(p => filterUnambiguousParts(p, second)).map(p => p.layer);
29+
}
30+
1131
function assignLabel(req, res, next, labelGenerator) {
1232

1333
// do nothing if there's nothing to process
1434
if (!res || !res.data) {
1535
return next();
1636
}
1737

38+
// This object will help for label deduplication
39+
const dedupLabel = {};
40+
41+
// First we assign for all result the default label with all required layers
1842
res.data.forEach(function (result) {
19-
result.label = labelGenerator(result);
43+
const { parts, separator } = labelGenerator(result);
44+
result.label = parts.filter(e => e.role === 'required').map(e => e.label).join(separator);
45+
dedupLabel[result.label] = dedupLabel[result.label] || [];
46+
dedupLabel[result.label].push({ result, parts, separator });
2047
});
2148

49+
// We check all values with more than one entry
50+
Object.values(dedupLabel)
51+
.filter(results => results.length > 1)
52+
.forEach(results => {
53+
// This array will contain all optional layers that should be displayed
54+
const bestLayers = getBestLayers(results);
55+
// We reassign the label with the new value
56+
results.forEach(({ result, parts, separator }) => {
57+
result.label = parts.filter(e => e.role === 'required' || bestLayers.indexOf(e.layer) >= 0).map(e => e.label).join(separator);
58+
});
59+
});
60+
2261
next();
2362
}
2463

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"morgan": "^1.8.2",
5151
"pelias-compare": "^0.1.16",
5252
"pelias-config": "^5.0.1",
53-
"pelias-labels": "^1.16.0",
53+
"pelias-labels": "pelias/labels#joxit/feat/with-optional",
5454
"pelias-logger": "^1.2.0",
5555
"pelias-microservice-wrapper": "^1.7.0",
5656
"pelias-model": "^9.0.0",

test/unit/middleware/assignLabels.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
var proxyquire = require('proxyquire').noCallThru();
22

3+
function partsGenerator(cb) {
4+
return { partsGenerator: cb };
5+
}
6+
37
module.exports.tests = {};
48

59
module.exports.tests.serialization = function(test, common) {
@@ -30,10 +34,10 @@ module.exports.tests.serialization = function(test, common) {
3034
test('labels should be assigned to all results', function(t) {
3135
var labelGenerator = function(result) {
3236
if (result.id === 1) {
33-
return 'label 1';
37+
return { parts: [{ label: 'label 1', role: 'required' }], separator: ', '};
3438
}
3539
if (result.id === 2) {
36-
return 'label 2';
40+
return { parts: [{ label: 'label 2', role: 'required' }], separator: ', '};
3741
}
3842

3943
};
@@ -73,11 +77,11 @@ module.exports.tests.serialization = function(test, common) {
7377

7478
test('no explicit labelGenerator supplied should use pelias-labels module', function(t) {
7579
var assignLabels = proxyquire('../../../middleware/assignLabels', {
76-
'pelias-labels': function(result) {
80+
'pelias-labels': partsGenerator(function(result) {
7781
if (result.id === 1) {
78-
return 'label 1';
82+
return { parts: [{ label: 'label 1', role: 'required' }], separator: ', '};
7983
}
80-
}
84+
})
8185
})();
8286

8387
var input = {

0 commit comments

Comments
 (0)