Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/contributors.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,21 @@ module.exports = function (app, _private = null) {
}

/**
* Builds an aggregation query that checks the resource index for counts on the contributorRoleLiteral field for a list of contributors.
* Builds an aggregation query that checks the resource index for counts on the browseableContributorRole_packed field for a list of contributors.
*/
const buildElasticRoleCountQuery = function (contributorList) {
return {
size: 0,
query: {
terms: {
contributorRoleLiteral: contributorList
browseableContributorRole_packed: contributorList
}
},
aggs: {
contributor_role: {
terms: {
script: {
source: 'def results = []; for (val in doc["contributorRoleLiteral"]) { int pos = val.indexOf("||"); if (pos != -1) { String name = val.substring(0, pos); if (params.targets.contains(name)) { results.add(val); } } } return results;',
source: 'def results = []; for (val in doc["browseableContributorRole_packed"]) { int pos = val.indexOf("||"); if (pos != -1) { String name = val.substring(0, pos); if (params.targets.contains(name)) { results.add(val); } } } return results;',
params: {
targets: contributorList
}
Expand Down
25 changes: 25 additions & 0 deletions lib/display-field-unpacker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const parseValueAndLabel = (delimitedString) => {
if (!delimitedString.includes('||')) {
return { value: delimitedString, display: null }
}
const [value, display] = delimitedString.split('||')
return { value, display }
}

module.exports = (elasticSearchResponse) => {
elasticSearchResponse.hits.hits.forEach((bib) => {
// Contributors and creators are packed like so <name>||<display label> where <display label>
// can have prefix, title, and roles. We'd like to unpack them in a friendly format for the frontend
// to display the full label and use the isolated name for link-building
Object.entries(bib._source).forEach(([key, value]) => {
if (key.endsWith('_displayPacked')) {
const fieldName = key.replace('_displayPacked', '')
bib._source[fieldName + 'Display'] = value.map((packedValue) => parseValueAndLabel(packedValue))
delete bib._source[key]
}
})

return bib
})
return elasticSearchResponse
}
2 changes: 1 addition & 1 deletion lib/elasticsearch/elastic-query-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class ElasticQueryBuilder {
* Concat contributor + role if role param is provided
*/
applyContributorRole () {
this.query.addMust(termMatch('contributorRoleLiteral', this.request.params.filters.contributorLiteral + '||' + this.request.params.role))
this.query.addMust(termMatch('browseableContributorRole_packed', this.request.params.filters.contributorLiteral + '||' + this.request.params.role))
}

/**
Expand Down
4 changes: 4 additions & 0 deletions lib/response_massager.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const LocationLabelUpdater = require('./location_label_updater')
const AvailabilityResolver = require('./availability_resolver.js')
const parallelFieldsExtractor = require('./parallel-fields-extractor')
const displayFieldUnpacker = require('./display-field-unpacker')
const { isAeonUrl, sortOnPropWithUndefinedLast } = require('../lib/util')
const FulfillmentResolver = require('./fulfillment_resolver')
const fixItemRequestability = require('./requestability_resolver')
Expand Down Expand Up @@ -73,6 +74,9 @@ class ResponseMassager {
// Rename parallel fields:
response = parallelFieldsExtractor(response)

// Extract display values and labels from packed fields
response = displayFieldUnpacker(response)

// Update ES response with updated availability from SCSB:
const updatedWithAvailability = (new AvailabilityResolver(response))
.responseWithUpdatedAvailability(options)
Expand Down
22 changes: 22 additions & 0 deletions test/display-field-unpacker.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const { expect } = require('chai')
const displayFieldsUnpacker = require('../lib/display-field-unpacker')
const packedDisplayBib = require('./fixtures/packed-display-response.json')

describe('Display field unpacker', () => {
describe('When a bib has a packed display property', () => {
it('adds each of the items in that array as unpacked objects', () => {
const displayFieldsUnpacked = displayFieldsUnpacker(packedDisplayBib).hits.hits[0]._source
expect(Object.keys(displayFieldsUnpacked).length).to.equal(2)
expect(displayFieldsUnpacked).to.deep.equal({
testDisplay: [
{ value: 'someValue', display: 'someDisplay' },
{ value: 'someValueB', display: 'someDisplayB' },
{ value: 'someValueC', display: null }
],
testOtherDisplay: [
{ value: 'otherValue', display: 'otherDisplay' }
]
})
})
})
})
2 changes: 1 addition & 1 deletion test/elastic-query-builder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ describe('ElasticQueryBuilder', () => {
const inst = ElasticQueryBuilder.forApiRequest(request)

expect(inst.query.toJson()).to.nested
.include({ 'bool.must[0].term.contributorRoleLiteral.value': 'Patinkin, Mandy||performer.' })
.include({ 'bool.must[0].term.browseableContributorRole_packed.value': 'Patinkin, Mandy||performer.' })
})
})

Expand Down
18 changes: 18 additions & 0 deletions test/fixtures/packed-display-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"hits": {
"hits": [
{
"_source": {
"test_displayPacked": [
"someValue||someDisplay",
"someValueB||someDisplayB",
"someValueC"
],
"testOther_displayPacked": [
"otherValue||otherDisplay"
]
}
}
]
}
}
Loading