Skip to content

Commit 166fc91

Browse files
authored
Merge pull request #923 from WatWowMap/pokestop-query-improvements
perf: improve pokestop querying perf by 10x
2 parents cfe7c38 + f696b67 commit 166fc91

2 files changed

Lines changed: 85 additions & 47 deletions

File tree

server/src/models/Pokestop.js

Lines changed: 78 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-continue */
12
const { Model, raw } = require('objection')
23
const i18next = require('i18next')
34
const config = require('@rm/config')
@@ -62,18 +63,6 @@ class Pokestop extends Model {
6263
return 'pokestop'
6364
}
6465

65-
/**
66-
*
67-
* @param {import('objection').QueryBuilder<Pokestop, Pokestop[]>} query
68-
* @param {boolean} isMad
69-
*/
70-
static onlyValid(query, isMad) {
71-
query.andWhere('enabled', true)
72-
if (!isMad) {
73-
query.andWhere('deleted', false)
74-
}
75-
}
76-
7766
static async getAll(
7867
perms,
7968
args,
@@ -189,7 +178,6 @@ class Pokestop extends Model {
189178
.whereBetween(isMad ? 'latitude' : 'lat', [args.minLat, args.maxLat])
190179
.andWhereBetween(isMad ? 'longitude' : 'lon', [args.minLon, args.maxLon])
191180

192-
Pokestop.onlyValid(query, isMad)
193181
if (!getAreaSql(query, areaRestrictions, onlyAreas, isMad)) {
194182
return []
195183
}
@@ -907,6 +895,7 @@ class Pokestop extends Model {
907895
const filtered = {}
908896
for (let i = 0; i < queryResults.length; i += 1) {
909897
const result = queryResults[i]
898+
if (!result.enabled || result.deleted) continue
910899
const quest = {}
911900
const invasion = {}
912901

@@ -954,6 +943,7 @@ class Pokestop extends Model {
954943
const filtered = {}
955944
for (let i = 0; i < queryResults.length; i += 1) {
956945
const result = queryResults[i]
946+
if (!result.enabled || result.deleted) continue
957947
const quest = { with_ar: true }
958948
const altQuest = { with_ar: false }
959949
const invasion = {}
@@ -1626,7 +1616,6 @@ class Pokestop extends Model {
16261616
if (!getAreaSql(query, perms.areaRestrictions, onlyAreas, isMad)) {
16271617
return []
16281618
}
1629-
Pokestop.onlyValid(query, isMad)
16301619
return query
16311620
}
16321621

@@ -1660,21 +1649,40 @@ class Pokestop extends Model {
16601649
.includes(search),
16611650
)
16621651

1652+
if (!pokemonIds.length && !itemIds.length && !rewardTypes.length) {
1653+
return []
1654+
}
16631655
const query = this.query()
16641656
.select([
1665-
'*',
16661657
isMad ? 'pokestop_id AS id' : 'id',
16671658
isMad ? 'latitude AS lat' : 'lat',
16681659
isMad ? 'longitude AS lon' : 'lon',
16691660
isMad ? 'quest_reward AS quest_rewards' : 'quest_rewards',
16701661
distance,
1662+
'name',
1663+
'quest_pokemon_id',
1664+
'quest_item_id',
1665+
'quest_reward_type',
1666+
'quest_title',
1667+
'quest_target',
16711668
])
16721669
.andWhere('quest_timestamp', '>=', midnight || 0)
16731670
.andWhere((quests) => {
1674-
quests
1675-
.whereIn('quest_pokemon_id', pokemonIds)
1676-
.orWhereIn('quest_item_id', itemIds)
1677-
.orWhereIn('quest_reward_type', rewardTypes)
1671+
if (pokemonIds.length === 1) {
1672+
quests.where('quest_pokemon_id', pokemonIds[0])
1673+
} else if (pokemonIds.length > 1) {
1674+
quests.whereIn('quest_pokemon_id', pokemonIds)
1675+
}
1676+
if (itemIds.length === 1) {
1677+
quests.orWhere('quest_item_id', itemIds[0])
1678+
} else if (itemIds.length > 1) {
1679+
quests.orWhereIn('quest_item_id', itemIds)
1680+
}
1681+
if (rewardTypes.length === 1) {
1682+
quests.orWhere('quest_reward_type', rewardTypes[0])
1683+
} else if (rewardTypes.length > 1) {
1684+
quests.orWhereIn('quest_reward_type', rewardTypes)
1685+
}
16781686
})
16791687
.limit(searchResultsLimit)
16801688
.orderBy('distance')
@@ -1690,21 +1698,39 @@ class Pokestop extends Model {
16901698
if (!getAreaSql(query, perms.areaRestrictions, onlyAreas, isMad)) {
16911699
return []
16921700
}
1693-
Pokestop.onlyValid(query, isMad)
1694-
1695-
const results = await query
1696-
const mapped = results.map((q) => ({ ...q, with_ar: q.with_ar ?? true }))
1697-
1701+
const queries = [query]
16981702
if (hasAltQuests) {
16991703
const altQuestQuery = this.query()
1700-
.select(['*', distance])
1701-
.where('deleted', false)
1704+
.select([
1705+
'id',
1706+
'lat',
1707+
'lon',
1708+
'name',
1709+
'alternative_quest_rewards',
1710+
'alternative_quest_pokemon_id',
1711+
'alternative_quest_item_id',
1712+
'alternative_quest_reward_type',
1713+
'alternative_quest_title',
1714+
'alternative_quest_target',
1715+
distance,
1716+
])
17021717
.andWhere('alternative_quest_timestamp', '>=', midnight || 0)
17031718
.andWhere((quests) => {
1704-
quests
1705-
.whereIn('alternative_quest_pokemon_id', pokemonIds)
1706-
.orWhereIn('alternative_quest_item_id', itemIds)
1707-
.orWhereIn('alternative_quest_reward_type', rewardTypes)
1719+
if (pokemonIds.length === 1) {
1720+
quests.where('alternative_quest_pokemon_id', pokemonIds[0])
1721+
} else if (pokemonIds.length > 1) {
1722+
quests.whereIn('alternative_quest_pokemon_id', pokemonIds)
1723+
}
1724+
if (itemIds.length === 1) {
1725+
quests.orWhere('alternative_quest_item_id', itemIds[0])
1726+
} else if (itemIds.length > 1) {
1727+
quests.orWhereIn('alternative_quest_item_id', itemIds)
1728+
}
1729+
if (rewardTypes.length === 1) {
1730+
quests.orWhere('alternative_quest_reward_type', rewardTypes[0])
1731+
} else if (rewardTypes.length > 1) {
1732+
quests.orWhereIn('alternative_quest_reward_type', rewardTypes)
1733+
}
17081734
})
17091735
.limit(searchResultsLimit)
17101736
.orderBy('distance')
@@ -1713,8 +1739,13 @@ class Pokestop extends Model {
17131739
) {
17141740
return []
17151741
}
1716-
const altQuestResults = await altQuestQuery
1717-
const remapped = altQuestResults.map((result) => ({
1742+
queries.push(altQuestQuery)
1743+
}
1744+
1745+
const [withAr, withoutAr] = await Promise.all(queries)
1746+
const mapped = withAr.map((q) => ({ ...q, with_ar: q.with_ar ?? true }))
1747+
if (withoutAr) {
1748+
const remapped = withoutAr.map((result) => ({
17181749
...result,
17191750
quest_rewards: result.alternative_quest_rewards,
17201751
quest_reward_type: result.alternative_quest_reward_type,
@@ -1725,14 +1756,16 @@ class Pokestop extends Model {
17251756
with_ar: false,
17261757
}))
17271758
mapped.push(...remapped)
1728-
mapped.sort((a, b) => a.distance - b.distance)
1729-
mapped.length = searchResultsLimit
17301759
}
1760+
1761+
mapped.sort((a, b) => a.distance - b.distance)
1762+
mapped.length = searchResultsLimit
1763+
17311764
return mapped
17321765
.map((result) =>
17331766
isMad ? this.parseMadRewards(result) : this.parseRdmRewards(result),
17341767
)
1735-
.filter((x) => x)
1768+
.filter(Boolean)
17361769
}
17371770

17381771
static async searchLures(perms, args, { isMad }, distance) {
@@ -1772,8 +1805,6 @@ class Pokestop extends Model {
17721805
if (!getAreaSql(query, perms.areaRestrictions, onlyAreas, isMad)) {
17731806
return []
17741807
}
1775-
Pokestop.onlyValid(query, isMad)
1776-
17771808
const results = await query
17781809
return results
17791810
}
@@ -1788,7 +1819,7 @@ class Pokestop extends Model {
17881819
.first()
17891820
}
17901821

1791-
static getSubmissions(perms, args, { isMad, hasShowcaseData }) {
1822+
static async getSubmissions(perms, args, { isMad, hasShowcaseData }) {
17921823
const {
17931824
filters: { onlyAreas = [], onlyIncludeSponsored = true },
17941825
minLat,
@@ -1806,9 +1837,14 @@ class Pokestop extends Model {
18061837
maxLon + 0.025,
18071838
])
18081839
if (isMad) {
1809-
query.select(['pokestop_id AS id', 'latitude AS lat', 'longitude AS lon'])
1840+
query.select([
1841+
'pokestop_id AS id',
1842+
'enabled',
1843+
'latitude AS lat',
1844+
'longitude AS lon',
1845+
])
18101846
} else {
1811-
query.select(['id', 'lat', 'lon', 'partner_id'])
1847+
query.select(['id', 'lat', 'lon', 'enabled', 'deleted', 'partner_id'])
18121848
if (!onlyIncludeSponsored) {
18131849
query.andWhere((poi) => {
18141850
poi.whereNull('partner_id').orWhere('partner_id', 0)
@@ -1821,9 +1857,9 @@ class Pokestop extends Model {
18211857
if (!getAreaSql(query, perms.areaRestrictions, onlyAreas, isMad)) {
18221858
return []
18231859
}
1824-
Pokestop.onlyValid(query, isMad)
1860+
const results = await query
18251861

1826-
return query
1862+
return results.filter((x) => x.enabled && !x.deleted)
18271863
}
18281864
}
18291865

server/src/services/DbCheck.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,18 @@ module.exports = class DbCheck {
109109
* @returns {ReturnType<typeof raw>}
110110
*/
111111
getDistance(args, isMad) {
112+
const radLat = args.lat * (Math.PI / 180)
113+
const radLon = args.lon * (Math.PI / 180)
112114
return raw(
113115
`ROUND(( ${
114116
this.distanceUnit === 'mi' ? '3959' : '6371'
115-
} * acos( cos( radians(${args.lat}) ) * cos( radians( ${
117+
} * acos( cos( ${radLat} ) * cos( radians( ${
116118
isMad ? 'latitude' : 'lat'
117-
} ) ) * cos( radians( ${isMad ? 'longitude' : 'lon'} ) - radians(${
118-
args.lon
119-
}) ) + sin( radians(${args.lat}) ) * sin( radians( ${
119+
} ) ) * cos( radians( ${
120+
isMad ? 'longitude' : 'lon'
121+
} ) - ${radLon} ) + sin( ${radLat} ) * sin( radians( ${
120122
isMad ? 'latitude' : 'lat'
121-
} ) ) ) ),2)`,
123+
} ) ) ) ), 2)`,
122124
).as('distance')
123125
}
124126

0 commit comments

Comments
 (0)