Skip to content

Commit

Permalink
perf: improve pokestop querying perf by 10x
Browse files Browse the repository at this point in the history
  • Loading branch information
TurtIeSocks committed Jan 17, 2024
1 parent cfe7c38 commit f696b67
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 47 deletions.
120 changes: 78 additions & 42 deletions server/src/models/Pokestop.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-continue */
const { Model, raw } = require('objection')
const i18next = require('i18next')
const config = require('@rm/config')
Expand Down Expand Up @@ -62,18 +63,6 @@ class Pokestop extends Model {
return 'pokestop'
}

/**
*
* @param {import('objection').QueryBuilder<Pokestop, Pokestop[]>} query
* @param {boolean} isMad
*/
static onlyValid(query, isMad) {
query.andWhere('enabled', true)
if (!isMad) {
query.andWhere('deleted', false)
}
}

static async getAll(
perms,
args,
Expand Down Expand Up @@ -189,7 +178,6 @@ class Pokestop extends Model {
.whereBetween(isMad ? 'latitude' : 'lat', [args.minLat, args.maxLat])
.andWhereBetween(isMad ? 'longitude' : 'lon', [args.minLon, args.maxLon])

Pokestop.onlyValid(query, isMad)
if (!getAreaSql(query, areaRestrictions, onlyAreas, isMad)) {
return []
}
Expand Down Expand Up @@ -907,6 +895,7 @@ class Pokestop extends Model {
const filtered = {}
for (let i = 0; i < queryResults.length; i += 1) {
const result = queryResults[i]
if (!result.enabled || result.deleted) continue
const quest = {}
const invasion = {}

Expand Down Expand Up @@ -954,6 +943,7 @@ class Pokestop extends Model {
const filtered = {}
for (let i = 0; i < queryResults.length; i += 1) {
const result = queryResults[i]
if (!result.enabled || result.deleted) continue
const quest = { with_ar: true }
const altQuest = { with_ar: false }
const invasion = {}
Expand Down Expand Up @@ -1626,7 +1616,6 @@ class Pokestop extends Model {
if (!getAreaSql(query, perms.areaRestrictions, onlyAreas, isMad)) {
return []
}
Pokestop.onlyValid(query, isMad)
return query
}

Expand Down Expand Up @@ -1660,21 +1649,40 @@ class Pokestop extends Model {
.includes(search),
)

if (!pokemonIds.length && !itemIds.length && !rewardTypes.length) {
return []
}
const query = this.query()
.select([
'*',
isMad ? 'pokestop_id AS id' : 'id',
isMad ? 'latitude AS lat' : 'lat',
isMad ? 'longitude AS lon' : 'lon',
isMad ? 'quest_reward AS quest_rewards' : 'quest_rewards',
distance,
'name',
'quest_pokemon_id',
'quest_item_id',
'quest_reward_type',
'quest_title',
'quest_target',
])
.andWhere('quest_timestamp', '>=', midnight || 0)
.andWhere((quests) => {
quests
.whereIn('quest_pokemon_id', pokemonIds)
.orWhereIn('quest_item_id', itemIds)
.orWhereIn('quest_reward_type', rewardTypes)
if (pokemonIds.length === 1) {
quests.where('quest_pokemon_id', pokemonIds[0])
} else if (pokemonIds.length > 1) {
quests.whereIn('quest_pokemon_id', pokemonIds)
}
if (itemIds.length === 1) {
quests.orWhere('quest_item_id', itemIds[0])
} else if (itemIds.length > 1) {
quests.orWhereIn('quest_item_id', itemIds)
}
if (rewardTypes.length === 1) {
quests.orWhere('quest_reward_type', rewardTypes[0])
} else if (rewardTypes.length > 1) {
quests.orWhereIn('quest_reward_type', rewardTypes)
}
})
.limit(searchResultsLimit)
.orderBy('distance')
Expand All @@ -1690,21 +1698,39 @@ class Pokestop extends Model {
if (!getAreaSql(query, perms.areaRestrictions, onlyAreas, isMad)) {
return []
}
Pokestop.onlyValid(query, isMad)

const results = await query
const mapped = results.map((q) => ({ ...q, with_ar: q.with_ar ?? true }))

const queries = [query]
if (hasAltQuests) {
const altQuestQuery = this.query()
.select(['*', distance])
.where('deleted', false)
.select([
'id',
'lat',
'lon',
'name',
'alternative_quest_rewards',
'alternative_quest_pokemon_id',
'alternative_quest_item_id',
'alternative_quest_reward_type',
'alternative_quest_title',
'alternative_quest_target',
distance,
])
.andWhere('alternative_quest_timestamp', '>=', midnight || 0)
.andWhere((quests) => {
quests
.whereIn('alternative_quest_pokemon_id', pokemonIds)
.orWhereIn('alternative_quest_item_id', itemIds)
.orWhereIn('alternative_quest_reward_type', rewardTypes)
if (pokemonIds.length === 1) {
quests.where('alternative_quest_pokemon_id', pokemonIds[0])
} else if (pokemonIds.length > 1) {
quests.whereIn('alternative_quest_pokemon_id', pokemonIds)
}
if (itemIds.length === 1) {
quests.orWhere('alternative_quest_item_id', itemIds[0])
} else if (itemIds.length > 1) {
quests.orWhereIn('alternative_quest_item_id', itemIds)
}
if (rewardTypes.length === 1) {
quests.orWhere('alternative_quest_reward_type', rewardTypes[0])
} else if (rewardTypes.length > 1) {
quests.orWhereIn('alternative_quest_reward_type', rewardTypes)
}
})
.limit(searchResultsLimit)
.orderBy('distance')
Expand All @@ -1713,8 +1739,13 @@ class Pokestop extends Model {
) {
return []
}
const altQuestResults = await altQuestQuery
const remapped = altQuestResults.map((result) => ({
queries.push(altQuestQuery)
}

const [withAr, withoutAr] = await Promise.all(queries)
const mapped = withAr.map((q) => ({ ...q, with_ar: q.with_ar ?? true }))
if (withoutAr) {
const remapped = withoutAr.map((result) => ({
...result,
quest_rewards: result.alternative_quest_rewards,
quest_reward_type: result.alternative_quest_reward_type,
Expand All @@ -1725,14 +1756,16 @@ class Pokestop extends Model {
with_ar: false,
}))
mapped.push(...remapped)
mapped.sort((a, b) => a.distance - b.distance)
mapped.length = searchResultsLimit
}

mapped.sort((a, b) => a.distance - b.distance)
mapped.length = searchResultsLimit

return mapped
.map((result) =>
isMad ? this.parseMadRewards(result) : this.parseRdmRewards(result),
)
.filter((x) => x)
.filter(Boolean)
}

static async searchLures(perms, args, { isMad }, distance) {
Expand Down Expand Up @@ -1772,8 +1805,6 @@ class Pokestop extends Model {
if (!getAreaSql(query, perms.areaRestrictions, onlyAreas, isMad)) {
return []
}
Pokestop.onlyValid(query, isMad)

const results = await query
return results
}
Expand All @@ -1788,7 +1819,7 @@ class Pokestop extends Model {
.first()
}

static getSubmissions(perms, args, { isMad, hasShowcaseData }) {
static async getSubmissions(perms, args, { isMad, hasShowcaseData }) {
const {
filters: { onlyAreas = [], onlyIncludeSponsored = true },
minLat,
Expand All @@ -1806,9 +1837,14 @@ class Pokestop extends Model {
maxLon + 0.025,
])
if (isMad) {
query.select(['pokestop_id AS id', 'latitude AS lat', 'longitude AS lon'])
query.select([
'pokestop_id AS id',
'enabled',
'latitude AS lat',
'longitude AS lon',
])
} else {
query.select(['id', 'lat', 'lon', 'partner_id'])
query.select(['id', 'lat', 'lon', 'enabled', 'deleted', 'partner_id'])
if (!onlyIncludeSponsored) {
query.andWhere((poi) => {
poi.whereNull('partner_id').orWhere('partner_id', 0)
Expand All @@ -1821,9 +1857,9 @@ class Pokestop extends Model {
if (!getAreaSql(query, perms.areaRestrictions, onlyAreas, isMad)) {
return []
}
Pokestop.onlyValid(query, isMad)
const results = await query

return query
return results.filter((x) => x.enabled && !x.deleted)
}
}

Expand Down
12 changes: 7 additions & 5 deletions server/src/services/DbCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,18 @@ module.exports = class DbCheck {
* @returns {ReturnType<typeof raw>}
*/
getDistance(args, isMad) {
const radLat = args.lat * (Math.PI / 180)
const radLon = args.lon * (Math.PI / 180)
return raw(
`ROUND(( ${
this.distanceUnit === 'mi' ? '3959' : '6371'
} * acos( cos( radians(${args.lat}) ) * cos( radians( ${
} * acos( cos( ${radLat} ) * cos( radians( ${
isMad ? 'latitude' : 'lat'
} ) ) * cos( radians( ${isMad ? 'longitude' : 'lon'} ) - radians(${
args.lon
}) ) + sin( radians(${args.lat}) ) * sin( radians( ${
} ) ) * cos( radians( ${
isMad ? 'longitude' : 'lon'
} ) - ${radLon} ) + sin( ${radLat} ) * sin( radians( ${
isMad ? 'latitude' : 'lat'
} ) ) ) ),2)`,
} ) ) ) ), 2)`,
).as('distance')
}

Expand Down

0 comments on commit f696b67

Please sign in to comment.