@natlibfi/melinda-record-matching 5.0.5 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/candidate-search/index.js.map +2 -2
- package/dist/candidate-search/index.test.js +1 -4
- package/dist/candidate-search/index.test.js.map +2 -2
- package/dist/candidate-search/query-list/auth.js +21 -0
- package/dist/candidate-search/query-list/auth.js.map +7 -0
- package/dist/candidate-search/query-list/auth.test.js +31 -0
- package/dist/candidate-search/query-list/auth.test.js.map +7 -0
- package/dist/candidate-search/query-list/bib.js +1 -1
- package/dist/candidate-search/query-list/bib.js.map +2 -2
- package/dist/candidate-search/query-list/bib.test.js +1 -4
- package/dist/candidate-search/query-list/bib.test.js.map +2 -2
- package/dist/candidate-search/query-list/component.js +1 -1
- package/dist/candidate-search/query-list/component.js.map +2 -2
- package/dist/candidate-search/query-list/index.js +8 -1
- package/dist/candidate-search/query-list/index.js.map +2 -2
- package/dist/cli.js +11 -1
- package/dist/cli.js.map +2 -2
- package/dist/index.js.map +2 -2
- package/dist/index.test.js.map +2 -2
- package/dist/match-detection/features/auth/index.js +2 -0
- package/dist/match-detection/features/auth/index.js.map +7 -0
- package/dist/match-detection/features/auth/index.test.js +37 -0
- package/dist/match-detection/features/auth/index.test.js.map +7 -0
- package/dist/match-detection/features/auth/yso.js +43 -0
- package/dist/match-detection/features/auth/yso.js.map +7 -0
- package/dist/match-detection/features/bib/index.test.js +1 -4
- package/dist/match-detection/features/bib/index.test.js.map +2 -2
- package/dist/match-detection/features/bib/isbn.js +0 -1
- package/dist/match-detection/features/bib/isbn.js.map +2 -2
- package/dist/match-detection/features/bib/issn.js +0 -1
- package/dist/match-detection/features/bib/issn.js.map +2 -2
- package/dist/match-detection/features/bib/language.js +0 -1
- package/dist/match-detection/features/bib/language.js.map +2 -2
- package/dist/match-detection/features/bib/media-type.js.map +2 -2
- package/dist/match-detection/features/bib/publication-time-allow-cons-years-multi.js +0 -1
- package/dist/match-detection/features/bib/publication-time-allow-cons-years-multi.js.map +2 -2
- package/dist/match-detection/features/bib/standard-identifier-factory.js.map +2 -2
- package/dist/match-detection/features/index.js +2 -1
- package/dist/match-detection/features/index.js.map +2 -2
- package/dist/match-detection/index.test.js +1 -5
- package/dist/match-detection/index.test.js.map +2 -2
- package/package.json +6 -3
- package/src/candidate-search/index.js +0 -2
- package/src/candidate-search/index.test.js +1 -6
- package/src/candidate-search/query-list/auth.js +25 -0
- package/src/candidate-search/query-list/auth.test.js +34 -0
- package/src/candidate-search/query-list/bib.js +1 -2
- package/src/candidate-search/query-list/bib.test.js +1 -5
- package/src/candidate-search/query-list/component.js +4 -4
- package/src/candidate-search/query-list/index.js +7 -1
- package/src/cli.js +13 -1
- package/src/index.js +0 -1
- package/src/index.test.js +0 -1
- package/src/match-detection/features/auth/index.js +1 -0
- package/src/match-detection/features/auth/index.test.js +47 -0
- package/src/match-detection/features/auth/yso.js +53 -0
- package/src/match-detection/features/bib/index.test.js +1 -6
- package/src/match-detection/features/bib/isbn.js +0 -1
- package/src/match-detection/features/bib/issn.js +0 -1
- package/src/match-detection/features/bib/language.js +0 -2
- package/src/match-detection/features/bib/media-type.js +0 -3
- package/src/match-detection/features/bib/publication-time-allow-cons-years-multi.js +0 -1
- package/src/match-detection/features/bib/standard-identifier-factory.js +0 -2
- package/src/match-detection/features/index.js +3 -1
- package/src/match-detection/index.test.js +1 -7
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import {describe} from 'node:test';
|
|
4
|
+
import createDebugLogger from 'debug';
|
|
5
|
+
import generateTests from '@natlibfi/fixugen';
|
|
6
|
+
import {READERS} from '@natlibfi/fixura';
|
|
7
|
+
import {MarcRecord} from '@natlibfi/marc-record';
|
|
8
|
+
import * as features from './index.js';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const debug = createDebugLogger('@natlibfi/melinda-record-matching:match-detection:features/auth:test');
|
|
12
|
+
const debugData = debug.extend('data');
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
describe('match-detection/features/auth/', () => {
|
|
16
|
+
generateTests({
|
|
17
|
+
path: [import.meta.dirname, '..', '..', '..', '..', 'test-fixtures', 'match-detection', 'features', 'auth'],
|
|
18
|
+
useMetadataFile: true,
|
|
19
|
+
fixura: {
|
|
20
|
+
reader: READERS.JSON
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
callback: ({feature, options, type, ...expectations}) => {
|
|
24
|
+
debug(`Testing: ${feature} ${type}`);
|
|
25
|
+
|
|
26
|
+
if (type === 'extract') {
|
|
27
|
+
const {expectedFeatures, inputRecord} = expectations;
|
|
28
|
+
const record = new MarcRecord(inputRecord, {subfieldValues: false});
|
|
29
|
+
debugData(`Record: ${record}`);
|
|
30
|
+
const {extract} = features[feature](options);
|
|
31
|
+
|
|
32
|
+
assert.deepStrictEqual(extract({record}), expectedFeatures);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (type === 'compare') {
|
|
37
|
+
const {featuresA, featuresB, expectedPoints} = expectations;
|
|
38
|
+
const {compare} = features[feature](options);
|
|
39
|
+
|
|
40
|
+
assert.equal(Math.round(compare(featuresA, featuresB) *100)/100, expectedPoints);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
throw new Error(`Invalid type ${type}`);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
|
|
2
|
+
import createDebugLogger from 'debug';
|
|
3
|
+
import {recordGetAuthURX} from '../../../candidate-search/query-list/auth.js';
|
|
4
|
+
|
|
5
|
+
const debug = createDebugLogger('@natlibfi/melinda-record-matching:match-detection:features:auth:yso');
|
|
6
|
+
const debugData = debug.extend('data');
|
|
7
|
+
|
|
8
|
+
function getSubjectHeadingThesaurus(record) {
|
|
9
|
+
// Quick'n'dirty: we could/should check 008/11 first. Now we just assume it is 'z'
|
|
10
|
+
const [f040] = record.get('040');
|
|
11
|
+
if (f040) {
|
|
12
|
+
// debug(`FOUND 040: ${fieldToString(f040)}`);
|
|
13
|
+
const sf = f040.subfields?.find(sf => sf.code === 'f');
|
|
14
|
+
if (sf) {
|
|
15
|
+
return sf.value;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default () => ({
|
|
22
|
+
name: 'yso',
|
|
23
|
+
extract: ({record/*, recordExternal*/}) => {
|
|
24
|
+
const identifiers = recordGetAuthURX(record);
|
|
25
|
+
|
|
26
|
+
const thesaurus = getSubjectHeadingThesaurus(record);
|
|
27
|
+
|
|
28
|
+
debug(`EXTRACT ${thesaurus}: ${identifiers.join(', ')}`);
|
|
29
|
+
return {identifiers, thesaurus};
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
compare: (aa, bb) => {
|
|
33
|
+
const aIdentifiers = aa.identifiers;
|
|
34
|
+
const aThesaurus = aa.thesaurus;
|
|
35
|
+
const bIdentifiers = bb.identifiers;
|
|
36
|
+
const bThesaurus = bb.thesaurus;
|
|
37
|
+
|
|
38
|
+
// Require identical existing thesauri
|
|
39
|
+
if (!aThesaurus || aThesaurus !== bThesaurus) {
|
|
40
|
+
return -1.0;
|
|
41
|
+
}
|
|
42
|
+
debugData(`Shared thesaurus: ${aThesaurus}`)
|
|
43
|
+
|
|
44
|
+
const sharedIdentifier = aIdentifiers.find(id => bIdentifiers.includes(id));
|
|
45
|
+
if (!sharedIdentifier) {
|
|
46
|
+
return -1.0;
|
|
47
|
+
}
|
|
48
|
+
debugData(`Shared identifier: ${sharedIdentifier} => MATCH`);
|
|
49
|
+
|
|
50
|
+
return 1.0;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
@@ -20,12 +20,7 @@ describe('match-detection/features/bib/', () => {
|
|
|
20
20
|
reader: READERS.JSON
|
|
21
21
|
},
|
|
22
22
|
|
|
23
|
-
callback: ({
|
|
24
|
-
|
|
25
|
-
if (!enabled) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
|
|
23
|
+
callback: ({feature, options, type, ...expectations}) => {
|
|
29
24
|
debug(`Testing: ${feature} ${type}`);
|
|
30
25
|
|
|
31
26
|
if (type === 'extract') {
|
|
@@ -16,7 +16,6 @@ export default () => ({
|
|
|
16
16
|
|
|
17
17
|
return record.get('020').filter(f => f.subfields?.some(sf => ['a', 'z'].includes(sf.code) && sf.value));
|
|
18
18
|
},
|
|
19
|
-
// eslint-disable-next-line max-statements
|
|
20
19
|
compare: (aa, bb) => {
|
|
21
20
|
debugData(`Comparing ISBN sets ${JSON.stringify(aa)} and ${JSON.stringify(bb)}`);
|
|
22
21
|
if (aa.length === 0 || bb.length === 0) {
|
|
@@ -37,7 +37,6 @@ export default () => ({
|
|
|
37
37
|
return /^[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9X]$/u.test(val);
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
|
-
// eslint-disable-next-line max-statements
|
|
41
40
|
compare: (aa, bb) => {
|
|
42
41
|
debugData(`Comparing ISSN sets ${JSON.stringify(aa)} and ${JSON.stringify(bb)}`);
|
|
43
42
|
if (aa.length === 0 || bb.length === 0) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import createDebugLogger from 'debug';
|
|
3
2
|
|
|
4
3
|
import {MarcRecord} from '@natlibfi/marc-record';
|
|
@@ -37,7 +36,6 @@ export default () => ({
|
|
|
37
36
|
// Should we return all the fields, or just the relevant fields?
|
|
38
37
|
return [clonedRecord.fields, label];
|
|
39
38
|
},
|
|
40
|
-
// eslint-disable-next-line max-statements
|
|
41
39
|
compare: (aa, bb) => {
|
|
42
40
|
const [a, aLabel] = aa;
|
|
43
41
|
const [b, bLabel] = bb;
|
|
@@ -147,7 +147,6 @@ export default () => ({
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
},
|
|
150
|
-
// eslint-disable-next-line max-statements
|
|
151
150
|
compare: (a, b) => {
|
|
152
151
|
const debug = createDebugLogger('@natlibfi/melinda-record-matching:match-detection:features/bib/publication-time-allow-cons-years-multi');
|
|
153
152
|
debug(`Comparing ${JSON.stringify(a)} to ${JSON.stringify(b)}`);
|
|
@@ -20,13 +20,7 @@ describe('match-detection', () => {
|
|
|
20
20
|
fixura: {
|
|
21
21
|
reader: READERS.JSON
|
|
22
22
|
},
|
|
23
|
-
callback: ({getFixture, options, expectedResults, array
|
|
24
|
-
|
|
25
|
-
if (!enabled) {
|
|
26
|
-
debug(`*** DISABLED TEST! ***`);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
23
|
+
callback: ({getFixture, options, expectedResults, array}) => {
|
|
30
24
|
const detect = createDetectionInterface(formatOptions());
|
|
31
25
|
const recordA = new MarcRecord(getFixture('recordA.json'), {subfieldValues: false});
|
|
32
26
|
debugData(inspect(recordA));
|