Skip to content
13 changes: 9 additions & 4 deletions src/controllers/locations.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,15 @@ export default {
const taxonomyIds = taxonomyId.split(',');
filterParameters.taxonomyIds = await models.Taxonomy.getAllIdsWithinTaxonomies(taxonomyIds);
}
const limit = pageSize || maxResults;

const offset = pageNumber !== undefined && pageSize !== undefined ?
pageNumber * pageSize : undefined;
const requestedLimit = pageSize || maxResults;
const maxDetailedResults = 200;
const limit = locationFieldsOnly
? requestedLimit
: Math.min(requestedLimit, maxDetailedResults);
Comment thread
Rovack marked this conversation as resolved.
Outdated
Comment thread
Rovack marked this conversation as resolved.
Outdated
Comment thread
Rovack marked this conversation as resolved.
Outdated

const offset = pageNumber !== undefined && limit !== undefined ?
pageNumber * limit : undefined;

const {
locations,
Expand All @@ -252,7 +257,7 @@ export default {
sortBy,
});
const plainLocations = await locations
.map(location => location.get({ plain: true }));
.map(location => (location.get ? location.get({ plain: true }) : location));
const paginationCount = Math.ceil(totalNumLocations / pageSize);

const formattedLocations = plainLocations.map((location) => {
Expand Down
82 changes: 41 additions & 41 deletions src/models/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ module.exports = (sequelize, DataTypes, Op) => {
return sequelize.and(requiredDocumentCondition, notRequiredDocumentCondition);
};

Location.findUniqueLocationIds = async (filterParameters,
Location.findUniqueLocationStubs = async (filterParameters,
additionalConditions,
originalQueryProps = {},
selectedAttributeForOrderBy, noServices) => {
Expand Down Expand Up @@ -390,14 +390,15 @@ module.exports = (sequelize, DataTypes, Op) => {
sequelize.models.Organization,
sequelize.models.PhysicalAddress,
sequelize.models.Phone,
sequelize.models.EventRelatedInfo,
{
model: sequelize.models.Service,
required: !noServices,
include: [
sequelize.models.Taxonomy,
sequelize.models.HolidaySchedule,
...(areRequiredDocsSpecified ? [sequelize.models.RequiredDocument] : []),
...((openAt && !occasion) ? [sequelize.models.RegularSchedule] : []),
...(occasion ? [sequelize.models.HolidaySchedule] : []),
...(servesZipcode ? [sequelize.models.ServiceArea] : []),
...(shouldJoinEligibilities ? [{
model: sequelize.models.Eligibility,
Expand Down Expand Up @@ -498,7 +499,7 @@ module.exports = (sequelize, DataTypes, Op) => {
// apply limit and offset in memory here
locations = locations.slice(offset || 0, limit ? (offset || 0) + limit : undefined);

return locations.map(location => location.id);
return locations;
};

Location.search = async ({
Expand All @@ -512,7 +513,7 @@ module.exports = (sequelize, DataTypes, Op) => {
sortBy,
noServices,
}) => {
let locationIds;
let locationStubs;
let distance;
let totalNumLocations;
// order is used to specify the attribute referenced in the ORDER BY
Expand Down Expand Up @@ -546,12 +547,12 @@ module.exports = (sequelize, DataTypes, Op) => {
if (radius && position) {
const distanceCondition = sequelize.where(distance, { [Op.lte]: radius });

totalNumLocations = (await Location.findUniqueLocationIds(
totalNumLocations = (await Location.findUniqueLocationStubs(
filterParameters,
[distanceCondition],
)).length;

locationIds = await Location.findUniqueLocationIds(
locationStubs = await Location.findUniqueLocationStubs(
filterParameters,
[distanceCondition].filter(Boolean), {
order,
Expand All @@ -568,54 +569,53 @@ module.exports = (sequelize, DataTypes, Op) => {
// However, filtering by window functions requires nested queries, which
// aren't natively supported by sequelize and would require a raw query.
// For now, the simplicity and security of sequelize seems worth the slight performance hit.
if (minResults && locationIds.length < minResults) {
totalNumLocations = (await Location.findUniqueLocationIds(filterParameters, [])).length;
locationIds = await Location.findUniqueLocationIds(filterParameters, [], {
if (minResults && locationStubs.length < minResults) {
totalNumLocations = (await Location.findUniqueLocationStubs(filterParameters, [])).length;
locationStubs = await Location.findUniqueLocationStubs(filterParameters, [], {
order,
limit: minResults,
offset,
}, selectedAttributeForOrderBy, noServices);
}
} else {
totalNumLocations = (await Location.findUniqueLocationIds(filterParameters, [])).length;
locationIds = await Location.findUniqueLocationIds(filterParameters, [], {
totalNumLocations = (await Location.findUniqueLocationStubs(filterParameters, [])).length;
locationStubs = await Location.findUniqueLocationStubs(filterParameters, [], {
limit,
offset,
order,
}, selectedAttributeForOrderBy);
}

const additionalLocationData = locationFieldsOnly ? [
sequelize.models.EventRelatedInfo,
{
model: sequelize.models.Service,
include: [
sequelize.models.HolidaySchedule,
],
},
] : [
sequelize.models.Organization,
sequelize.models.EventRelatedInfo,
{
model: sequelize.models.Service,
include: [
sequelize.models.Taxonomy,
sequelize.models.RequiredDocument,
sequelize.models.HolidaySchedule,
],
},
sequelize.models.Phone,
sequelize.models.PhysicalAddress,
];
const locationIds = locationStubs.map(location => location.id);

const locationsWithAssociations = await Location.findAll({
attributes: {
include: selectedAttributeForOrderBy ? [selectedAttributeForOrderBy] : undefined,
},
where: { id: { [Op.in]: locationIds } },
include: additionalLocationData,
order,
});
let locationsWithAssociations;
if (locationFieldsOnly) {
locationsWithAssociations = locationStubs;
Comment thread
Rovack marked this conversation as resolved.
Comment thread
Rovack marked this conversation as resolved.
} else {
Comment thread
Rovack marked this conversation as resolved.
const additionalLocationData = [
sequelize.models.Organization,
sequelize.models.EventRelatedInfo,
{
model: sequelize.models.Service,
include: [
sequelize.models.Taxonomy,
sequelize.models.RequiredDocument,
sequelize.models.HolidaySchedule,
],
},
sequelize.models.Phone,
sequelize.models.PhysicalAddress,
];

locationsWithAssociations = await Location.findAll({
attributes: {
include: selectedAttributeForOrderBy ? [selectedAttributeForOrderBy] : undefined,
},
where: { id: { [Op.in]: locationIds } },
include: additionalLocationData,
order,
});
}

function sortByLocationIds(a, b) {
return locationIds.indexOf(a.id) - locationIds.indexOf(b.id);
Expand Down
Loading