Skip to content

Commit fb586b4

Browse files
committed
feat(assignLabels): improve duplicate label handling
1 parent 8d72ac1 commit fb586b4

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

middleware/assignLabels.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const _ = require('lodash');
22

3-
const defaultLabelGenerator = require('pelias-labels');
3+
const defaultLabelGenerator = require('pelias-labels').partsGenerator;
44

55
function setup(labelGenerator) {
66
function middleware(req, res, next) {
@@ -10,17 +10,55 @@ function setup(labelGenerator) {
1010
return middleware;
1111
}
1212

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

1534
// do nothing if there's nothing to process
1635
if (!res || !res.data) {
1736
return next();
1837
}
1938

39+
// This object will help for label deduplication
40+
const dedupLabel = {};
41+
42+
// First we assign for all result the default label with all required layers
2043
res.data.forEach(function (result) {
21-
result.label = labelGenerator(result, _.get(req, 'clean.lang.iso6393'));
44+
const { labelParts, separator } = labelGenerator(result, _.get(req, 'clean.lang.iso6393'));
45+
result.label = labelParts.filter(e => e.role === 'required').map(e => e.label).join(separator);
46+
dedupLabel[result.label] = dedupLabel[result.label] || [];
47+
dedupLabel[result.label].push({ result, labelParts, separator });
2248
});
2349

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

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.19.0",
53+
"pelias-labels": "pelias/labels#joxit/feat/with-optional",
5454
"pelias-logger": "^1.2.0",
5555
"pelias-microservice-wrapper": "^1.10.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 { labelParts: [{ label: 'label 1', role: 'required' }], separator: ', '};
3438
}
3539
if (result.id === 2) {
36-
return 'label 2';
40+
return { labelParts: [{ 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 { labelParts: [{ label: 'label 1', role: 'required' }], separator: ', '};
7983
}
80-
}
84+
})
8185
})();
8286

8387
var input = {

0 commit comments

Comments
 (0)