1 | 'use strict';
|
2 |
|
3 | const fetchres = require('fetchres');
|
4 | const logger = require('ft-next-logger').logger;
|
5 | const signedFetch = require('signed-aws-es-fetch');
|
6 | const elasticAgent = require('./utils/elastic-agent');
|
7 |
|
8 | function formatDateRange(from, to) {
|
9 | const dateFrom = new Date();
|
10 | const dateTo = new Date();
|
11 |
|
12 | dateFrom.setDate(dateFrom.getDate() - from);
|
13 | dateTo.setDate(dateTo.getDate() - to);
|
14 |
|
15 | return {
|
16 | gte: dateFrom.toISOString(),
|
17 | lt: dateTo.toISOString()
|
18 | };
|
19 | }
|
20 |
|
21 | function formatPostBody(options) {
|
22 | return {
|
23 | size: 0,
|
24 | query: {
|
25 | bool: {
|
26 | must: [
|
27 | {
|
28 | term: { 'metadata.idV1': options.id }
|
29 | },
|
30 | {
|
31 | range: {
|
32 | 'publishedDate': formatDateRange(options.range || 60, 1)
|
33 | }
|
34 | }
|
35 | ]
|
36 | }
|
37 | },
|
38 | aggs: {
|
39 | tags: {
|
40 | nested: {
|
41 | path: 'metadata'
|
42 | },
|
43 | aggs: {
|
44 | filtered: {
|
45 | filter: {
|
46 | bool: {
|
47 | should: options.taxonomies.map(taxonomy => {
|
48 | return { term: { taxonomy: taxonomy } };
|
49 | })
|
50 | }
|
51 | },
|
52 | aggs: {
|
53 | suggestions: {
|
54 | terms: {
|
55 | field: 'idV1',
|
56 | exclude: options.id,
|
57 | size: options.size || 12,
|
58 | min_doc_count: 1
|
59 | },
|
60 | aggs: {
|
61 | prefLabel: {
|
62 | terms: {
|
63 | field: 'prefLabel',
|
64 | size: 1
|
65 | }
|
66 | },
|
67 | taxonomy: {
|
68 | terms: {
|
69 | field: 'taxonomy',
|
70 | size: 1
|
71 | }
|
72 | }
|
73 | }
|
74 | }
|
75 | }
|
76 | }
|
77 | }
|
78 | }
|
79 | }
|
80 | };
|
81 | }
|
82 |
|
83 | function mapResponseBucketsToTags(aggregations) {
|
84 | return aggregations.tags.filtered.suggestions.buckets.map(bucket => {
|
85 | return {
|
86 | idV1: bucket.key,
|
87 | taxonomy: bucket.taxonomy.buckets[0].key,
|
88 | prefLabel: bucket.prefLabel.buckets[0].key
|
89 | };
|
90 | });
|
91 | }
|
92 |
|
93 | module.exports = (options) => {
|
94 | const postBody = formatPostBody(options);
|
95 |
|
96 | return signedFetch('https://next-elastic.ft.com/v3_api_v2/item/_search', {
|
97 | retry: 0,
|
98 | body: JSON.stringify(postBody),
|
99 | method: 'POST',
|
100 | timeout: 3000,
|
101 | agent: elasticAgent
|
102 | })
|
103 | .then(response => {
|
104 | if (response.ok) {
|
105 | return fetchres.json(response);
|
106 | } else {
|
107 | logger.warn(`Failed getting related tags for: ${JSON.stringify(options, null, 2)}`);
|
108 | return {};
|
109 | }
|
110 | })
|
111 | .then(data => {
|
112 |
|
113 | if (data.took > 200) {
|
114 | logger.warn(`Slow response for related tags query: ${data.took}ms`);
|
115 | }
|
116 |
|
117 | return data.aggregations
|
118 | ? mapResponseBucketsToTags(data.aggregations)
|
119 | : [];
|
120 | });
|
121 | };
|