Skip to content
2 changes: 1 addition & 1 deletion data/buildingLocations.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{ "value": "ma", "label": "Stephen A. Schwarzman Building (SASB)","nickname": "SASB" }, { "value": "pa", "label": "The New York Public Library for the Performing Arts (LPA)","nickname": "LPA" },{ "value": "sc", "label": "Schomburg Center for Research in Black Culture","nickname": "Schomburg" },{ "value": "rc", "label": "Offsite - request in advance"},{ "value": "bu", "label": "Stavros Niarchos Foundation Library (SNFL)", "nickname": "SNFL" }]
[{ "value": "ma", "label": "Stephen A. Schwarzman Building (SASB)", "shortLabel": "Stephen A. Schwarzman Building", "nickname": "SASB" }, { "value": "pa", "shortLabel": "The New York Public Library for the Performing Arts", "label": "The New York Public Library for the Performing Arts (LPA)","nickname": "LPA" },{ "value": "sc", "label": "Schomburg Center for Research in Black Culture", "shortLabel": "Schomburg Center for Research in Black Culture", "nickname": "Schomburg" },{ "value": "rc", "label": "Offsite - request in advance", "shortLabel": "Offsite"},{ "value": "bu", "label": "Stavros Niarchos Foundation Library (SNFL)", "shortLabel": "Stavros Niarchos Foundation Library", "nickname": "SNFL" }]
26 changes: 26 additions & 0 deletions lib/jsonld_serializers.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,12 @@ ResourceSerializer.formatItemFilterAggregations = function (aggregations) {
// If it's a packed value, parse out the value and label:
if (value.split('||').length === 2) {
;[value, label] = value.split('||')
// For item location, add the buildingLocation label
} else if (field === 'location') {
const loc = buildingLocations.find(l => l.value === value)
if (loc) {
label = loc.shortLabel
}
}
return {
value,
Expand Down Expand Up @@ -380,6 +386,11 @@ class ItemResourceSerializer extends JsonLdItemSerializer {
stmts.holdingLocation = ItemResourceSerializer.getFormattedHoldingLocation(this.body.holdingLocation)
}

const buildingLocation = ItemResourceSerializer.getBuildingLocation(this.body.holdingLocation)
if (buildingLocation) {
stmts.buildingLocation = buildingLocation
}

if (this.body.collectionId) {
stmts.collection = ResourceSerializer.getFormattedCollections(this.body.collectionId)
delete stmts.collectionId
Expand Down Expand Up @@ -411,6 +422,21 @@ class ItemResourceSerializer extends JsonLdItemSerializer {
}]
}

static getBuildingLocation (location) {
const loc = Array.isArray(location) ? location[0] : location
const parentLoc = loc?.['@id']?.split(':')[1]?.substring(0, 2)
if (parentLoc) {
const building = buildingLocations.find(l => l.value === parentLoc)
if (building) {
return [{
'@id': building.value,
prefLabel: building.shortLabel
}]
}
}
return null

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since buildingLocation is calculated from holdingLocation, partner items will continue to return nothing for both. This case is already accounted for on the frontend

}

// Given an item, returns item with an added `identifier`
// of form 'urn:[sourceIdentifierPrefix]:[sourceIdentifier]'
// e.g.
Expand Down
24 changes: 21 additions & 3 deletions lib/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,19 @@ const Item = require('./models/Item.js')
const RESOURCES_INDEX = process.env.RESOURCES_INDEX

const ITEM_FILTER_AGGREGATIONS = {
item_location: { nested: { path: 'items' }, aggs: { _nested: { terms: { size: 100, field: 'items.holdingLocation_packed' } } } },
item_location: {
nested: { path: 'items' },
aggs: {
_nested: {
terms: {
size: 100,
script: {
source: "def locs = doc['items.holdingLocation.id']; if (locs.size() == 0) return null; def loc = locs.value; int colonIdx = loc.indexOf(':'); if (colonIdx == -1) return null; def locId = loc.substring(colonIdx + 1); if (locId.length() < 2) return null; def parentLoc = locId.substring(0, 2); if (['ma', 'pa', 'sc', 'rc', 'bu'].contains(parentLoc)) { return parentLoc; } return null;"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few questions about this script!

  • This instance and the one below seem substantially similar. Is there in value in refactoring them out to a const and then just changing the returns? Would make things a bit easier to maintain
  • Any performance concerns with executing such a complicated Painless script? I think there are other ways to achieve this but they might not be possible with how the index is currently configured.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved out to util.js. There is a performance cost (doesn't have to compile every time but it's still slower than a native ES query), and yes wouldn't have to do this if we indexed the building location ID on the item. Decided on this approach since it'll be faster to get out than a full reindex but could put that approach on the docket for upcoming reindexes?

}
}
}
}
},
item_status: { nested: { path: 'items' }, aggs: { _nested: { terms: { size: 100, field: 'items.status_packed' } } } },
item_format: { nested: { path: 'items' }, aggs: { _nested: { terms: { size: 100, field: 'items.formatLiteral' } } } }
}
Expand Down Expand Up @@ -212,6 +224,7 @@ module.exports = function (app, _private = null) {
}).then((resp) => {
const hitsAndItemAggregations = resp.hits.hits[0]._source
hitsAndItemAggregations.itemAggregations = resp.aggregations

return ResourceSerializer.serialize(hitsAndItemAggregations, Object.assign(opts, { root: true }))
})
})
Expand Down Expand Up @@ -488,8 +501,13 @@ module.exports = function (app, _private = null) {
},
location: (locations) => {
return {
terms: {
'items.holdingLocation.id': locations
script: {
script: {
source: "def locs = doc['items.holdingLocation.id']; if (locs.size() == 0) return false; def loc = locs.value; int colonIdx = loc.indexOf(':'); if (colonIdx == -1) return false; def locId = loc.substring(colonIdx + 1); if (locId.length() < 2) return false; def parentLoc = locId.substring(0, 2); return ['ma', 'pa', 'sc', 'rc', 'bu'].contains(parentLoc) && params.locations.contains(parentLoc);",
params: {
locations
}
}
}
}
},
Expand Down
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading