Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add all_items param to resources findByUri route #402

Merged
merged 12 commits into from
Sep 10, 2024
52 changes: 28 additions & 24 deletions lib/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ module.exports = function (app, _private = null) {
app.resources.findByUri = function (params, opts = {}, request) {
// Parse all params we support:
params = parseParams(params, {
all_items: { type: 'boolean', default: false },
uri: { type: 'string' },
itemUri: { type: 'string' },
items_size: { type: 'int', default: 100, range: [0, 200] },
Expand Down Expand Up @@ -228,6 +229,9 @@ module.exports = function (app, _private = null) {
.then((recapBarcodesByStatus) => {
// Establish base query:
let body = {
_source: {
excludes: EXCLUDE_FIELDS
},
size: 1,
query: {
bool: {
Expand All @@ -239,38 +243,39 @@ module.exports = function (app, _private = null) {
}
]
}
},
_source: {
excludes: EXCLUDE_FIELDS.concat(['items'])
}
}

// No specific item requested, so add pagination and matching params:
const itemsOptions = {
size: params.items_size,
from: params.items_from,
merge_checkin_card_items: params.merge_checkin_card_items,
query: {
volume: params.item_volume,
date: params.item_date,
format: params.item_format,
location: params.item_location,
status: params.item_status,
itemUri: params.itemUri
},
unavailable_recap_barcodes: recapBarcodesByStatus['Not Available']
if (params.all_items) {
body._source.excludes = EXCLUDE_FIELDS.filter((field) => field !== '*_sort')
}
if (!params.all_items) {
// No specific item requested, so add pagination and matching params:
const itemsOptions = {
size: params.items_size,
from: params.items_from,
merge_checkin_card_items: params.merge_checkin_card_items,
query: {
volume: params.item_volume,
date: params.item_date,
format: params.item_format,
location: params.item_location,
status: params.item_status,
itemUri: params.itemUri
},
unavailable_recap_barcodes: recapBarcodesByStatus['Not Available']
}
body = addInnerHits(body, itemsOptions)
body._source = {
excludes: EXCLUDE_FIELDS.concat(['items'])
}
}
body = addInnerHits(body, itemsOptions)

if (params.include_item_aggregations) {
body.aggregations = ITEM_FILTER_AGGREGATIONS
}

app.logger.debug('Resources#findByUri', body)
return app.esClient.search(body)
.then((resp) => {
resp = resp.body

// Mindfully throw errors for known issues:
if (!resp || !resp.hits) {
throw new Error('Error connecting to index')
Expand Down Expand Up @@ -723,11 +728,10 @@ module.exports = function (app, _private = null) {
return app.esClient.search(body)
.then((resp) => {
resp = resp.body

const massagedResponse = new ResponseMassager(resp)
return massagedResponse.massagedResponse(request)
.catch((e) => {
// If error hitting HTC, just return response un-modified:
// If error hitting HTC, just return response un-modified:
return resp
})
.then((updatedResponse) => ResourceResultsSerializer.serialize(updatedResponse, opts))
Expand Down
11 changes: 7 additions & 4 deletions lib/response_massager.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ const parallelFieldsExtractor = require('./parallel-fields-extractor')
const { isAeonUrl } = require('../lib/util')
const FulfillmentResolver = require('./fulfillment_resolver')
const RequestabilityResolver = require('./requestability_resolver')
// const addNumItemsMatched = require('./item-match-numerator')

class ResponseMassager {
constructor (responseReceived) {
Expand All @@ -16,11 +15,15 @@ class ResponseMassager {
* if it contains hits that have "items" or "electronicResources" inner_hits,
* reassigns those hits to ".items" and ".electronicResources" so that later
* code can access them as if that's where they were indexed that way.
* Conditionally sorts on enumerationChronology_sort.
*
* Also copies ".total" properties into convenient places for serialization.
*/
processInnerHitsProperties (response) {
processInnerHitsProperties (response, sortOnEnumerationChronology) {
response.hits.hits.forEach((hit) => {
if (sortOnEnumerationChronology) {
hit._source.items.sort((a, b) => a.enumerationChronology_sort[0] > b.enumerationChronology_sort[0] ? -1 : 1)
}
// Process "items" inner_hits
if (hit.inner_hits && hit.inner_hits.items) {
// Reassign items inner_hits to .items
Expand Down Expand Up @@ -58,10 +61,10 @@ class ResponseMassager {

massagedResponse (request, options = {}) {
let response = this.elasticSearchResponse

const allItemsBibQuery = request?.query?.all_items
// Inspect response inner_hits queries and move properties around to ease
// serialization:
response = this.processInnerHitsProperties(response)
response = this.processInnerHitsProperties(response, allItemsBibQuery)

// Rename parallel fields:
response = parallelFieldsExtractor(response)
Expand Down
25 changes: 23 additions & 2 deletions routes/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,28 @@ module.exports = function (app) {
next()
})

const standardParams = ['page', 'per_page', 'q', 'filters', 'expandContext', 'ext', 'field', 'sort', 'sort_direction', 'search_scope', 'items_size', 'items_from', 'contributor', 'title', 'subject', 'isbn', 'issn', 'lccn', 'oclc', 'merge_checkin_card_items', 'include_item_aggregations']
const standardParams = ['page',
'per_page',
'q',
'filters',
'expandContext',
'ext',
'field',
'sort',
'sort_direction',
'search_scope',
'all_items',
'items_size',
'items_from',
'contributor',
'title',
'subject',
'isbn',
'issn',
'lccn',
'oclc',
'merge_checkin_card_items',
'include_item_aggregations']

const respond = (res, _resp, params) => {
let contentType = 'application/ld+json'
Expand Down Expand Up @@ -104,7 +125,7 @@ module.exports = function (app) {
* e.g. discovery/resources/b1234
*/
app.get(`/api/v${VER}/discovery/resources/:uri.:ext?`, function (req, res) {
const gatheredParams = gatherParams(req, ['uri', 'items_size', 'items_from', 'merge_checkin_card_items', 'include_item_aggregations'])
const gatheredParams = gatherParams(req, ['uri', 'items_size', 'items_from', 'merge_checkin_card_items', 'include_item_aggregations', 'all_items'])
const params = Object.assign({}, req.query, { uri: req.params.uri })

if (Number.isInteger(parseInt(gatheredParams.items_size))) params.items_size = gatheredParams.items_size
Expand Down
Loading
Loading