Skip to content

Commit

Permalink
Merge pull request #401 from NYPL/SCC-4167/all-items
Browse files Browse the repository at this point in the history
Scc 4167/all items
  • Loading branch information
charmingduchess authored Sep 10, 2024
2 parents 8c9293f + 2140cd2 commit 63740f9
Show file tree
Hide file tree
Showing 30 changed files with 159,110 additions and 44 deletions.
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
13 changes: 8 additions & 5 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

0 comments on commit 63740f9

Please sign in to comment.