Skip to content

Commit 6e66206

Browse files
committed
Bones of browse/contributors
1 parent 2a38583 commit 6e66206

File tree

3 files changed

+146
-0
lines changed

3 files changed

+146
-0
lines changed

lib/contributors.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
const ElasticQuery = require('./elastic-query')
2+
3+
class ElasticQueryContributorsBuilder {
4+
constructor (apiRequest) {
5+
this.request = apiRequest
6+
this.query = new ElasticQuery()
7+
8+
switch (this.request.params.search_scope) {
9+
case 'has':
10+
this.requireContainingMatch()
11+
break
12+
case 'starts_with':
13+
this.requirePrefixMatch()
14+
break
15+
default:
16+
this.requireTermMatch()
17+
}
18+
}
19+
20+
/**
21+
* Match on the start of a preferred term
22+
*/
23+
requirePrefixMatch () {
24+
25+
}
26+
27+
/**
28+
* Require exact term match on preferred term or variants
29+
*/
30+
requireTermMatch () {
31+
32+
}
33+
34+
/**
35+
* Require general "and" match on provided query
36+
*/
37+
requireContainingMatch () {
38+
39+
}
40+
41+
/**
42+
* Create a ElasticQueryBuilder for given ApiRequest instance
43+
*/
44+
static forApiRequest (request) {
45+
return new ElasticQueryContributorsBuilder(request)
46+
}
47+
}
48+
49+
module.exports = ElasticQueryContributorsBuilder

routes/resources.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ module.exports = function (app) {
5252
.catch((error) => next(error))
5353
})
5454

55+
app.get(`/api/v${VER}/discovery/browse/contributors`, function (req, res, next) {
56+
const params = req.query
57+
58+
return app.contributors.browse(params, { baseUrl: app.baseUrl }, req)
59+
.then((resp) => respond(res, resp, params))
60+
.catch((error) => next(error))
61+
})
62+
5563
app.get(`/api/v${VER}/discovery/vocabularies`, function (req, res, next) {
5664
const params = Object.assign({}, req.query, req.params)
5765

0 commit comments

Comments
 (0)