|
| 1 | +const { parseParams } = require('../lib/util') |
| 2 | + |
| 3 | +const ApiRequest = require('./api-request') |
| 4 | +const ElasticQueryContributorsBuilder = require('./elasticsearch/elastic-query-contributors-builder') |
| 5 | + |
| 6 | +const CONTRIBUTORS_INDEX = process.env.CONTRIBUTORS_INDEX |
| 7 | + |
| 8 | +const SEARCH_SCOPES = [ |
| 9 | + 'has', |
| 10 | + 'starts_with' |
| 11 | +] |
| 12 | + |
| 13 | +const SORT_FIELDS = [ |
| 14 | + 'contributorName', |
| 15 | + 'count', |
| 16 | + 'relevance' |
| 17 | +] |
| 18 | + |
| 19 | +// Default sort orders for different search scopes |
| 20 | +const SEARCH_SCOPE_SORT_ORDER = { |
| 21 | + has: 'count', |
| 22 | + starts_with: 'contributorName' |
| 23 | +} |
| 24 | + |
| 25 | +const parseBrowseParams = function (params) { |
| 26 | + return parseParams(params, { |
| 27 | + q: { type: 'string' }, |
| 28 | + page: { type: 'int', default: 1 }, |
| 29 | + per_page: { type: 'int', default: 50, range: [0, 100] }, |
| 30 | + sort: { type: 'string', range: SORT_FIELDS, default: SEARCH_SCOPE_SORT_ORDER[params.search_scope] || 'termLabel' }, |
| 31 | + sort_direction: { type: 'string', range: ['asc', 'desc'] }, |
| 32 | + search_scope: { type: 'string', range: SEARCH_SCOPES, default: '' } |
| 33 | + }) |
| 34 | +} |
| 35 | + |
| 36 | +module.exports = function (app, _private = null) { |
| 37 | + app.subjects = {} |
| 38 | + |
| 39 | + app.subjects.browse = function (params, opts, request) { |
| 40 | + app.logger.debug('Unparsed params: ', params) |
| 41 | + params = parseBrowseParams(params) |
| 42 | + |
| 43 | + app.logger.debug('Parsed params: ', params) |
| 44 | + |
| 45 | + const body = buildElasticContributorsBody(params) |
| 46 | + |
| 47 | + app.logger.debug('Contrbutors#browse', CONTRIBUTORS_INDEX, body) |
| 48 | + |
| 49 | + return app.esClient.search(body, process.env.SUBJECTS_INDEX) |
| 50 | + .then((resp) => { |
| 51 | + return { |
| 52 | + '@type': 'contributorList', |
| 53 | + page: params.page, |
| 54 | + per_page: params.per_page, |
| 55 | + totalResults: resp.hits?.total?.value, |
| 56 | + contributors: resp.hits?.hits?.map((hit) => { |
| 57 | + // TODO: parse ES response into frontend-friendly format |
| 58 | + return {} |
| 59 | + }) |
| 60 | + } |
| 61 | + }) |
| 62 | + } |
| 63 | + |
| 64 | + // For unit testing |
| 65 | + if (_private && typeof _private === 'object') { |
| 66 | + _private.buildElasticContributorsBody = buildElasticContributorsBody |
| 67 | + _private.parseBrowseParams = parseBrowseParams |
| 68 | + } |
| 69 | +} |
| 70 | + |
| 71 | +/** |
| 72 | + * Given GET params, returns a plainobject with `from`, `size`, `query`, |
| 73 | + * `sort`, and any other params necessary to perform the ES query based |
| 74 | + * on the GET params. |
| 75 | + * |
| 76 | + * @return {object} An object that can be posted directly to ES |
| 77 | + */ |
| 78 | +const buildElasticContributorsBody = function (params) { |
| 79 | + const body = { |
| 80 | + from: (params.per_page * (params.page - 1)), |
| 81 | + size: params.per_page |
| 82 | + } |
| 83 | + |
| 84 | + const request = ApiRequest.fromParams(params) |
| 85 | + const builder = ElasticQueryContributorsBuilder.forApiRequest(request) |
| 86 | + |
| 87 | + body.query = builder.query.toJson() |
| 88 | + return body |
| 89 | +} |
0 commit comments