Skip to content
This repository was archived by the owner on Dec 20, 2024. It is now read-only.

Commit 7c62323

Browse files
author
Peter Schmalfeldt
committed
Add support to store search results as JSON with unique cache key for URL param.
Way faster to store cached results per unique search vs refetching the data each time. Data will only change monthly, at most, so once a unique search is done, there is no need to do it again. There is a cache clear process added to the NPM scripts so after restarting the server, all saved cached will be removed. Lots of disc space on the server, so this is a way more performant solution.
1 parent b691157 commit 7c62323

File tree

4 files changed

+100
-50
lines changed

4 files changed

+100
-50
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,4 @@ public/sitemap-*.xml
6161
public/robots.txt
6262

6363
*.log
64+
.cache/*.json

package-lock.json

Lines changed: 28 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"postbuild": "next-sitemap --config next-sitemap.config.mjs",
1414
"start": "next start",
1515
"lint": "next lint",
16-
"clean": "rm -fr dist && rm -fr .next",
16+
"clean": "rm -fr .cache/*.json && rm -fr dist && rm -fr .next",
1717
"cli:init": "DEBUG=sfcc-docs:* bin/cli.mjs init --verbose",
1818
"cli:prep": "DEBUG=sfcc-docs:* bin/cli.mjs prep --verbose",
1919
"cli:update-links": "DEBUG=sfcc-docs:* bin/cli.mjs update-links --verbose",
@@ -66,6 +66,7 @@
6666
"fast-glob": "^3.2.12",
6767
"flexsearch": "^0.7.31",
6868
"focus-visible": "^5.2.0",
69+
"md5": "^2.3.0",
6970
"next": "13.4.2",
7071
"next-pwa": "^5.6.0",
7172
"postcss-focus-visible": "^6.0.4",

src/pages/api/search.jsx

Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,79 @@
1+
import 'dotenv/config'
2+
import fs from 'fs'
3+
import md5 from 'md5'
4+
15
import { getMeta } from '@/data/meta'
26
import { currentVersion } from '@/data/versions'
3-
import 'dotenv/config'
47

58
export default function handler(req, res) {
6-
// Load Search Function
7-
import('@/markdoc/search.mjs').then(({ search }) => {
9+
// Setup Cache Key
10+
const hashKey = md5(`hash-${req.query.query}-${req.query.limit || 100}-${req.query.offset || 0}`)
11+
const cacheFile = process.cwd() + `/.cache/${hashKey}.json`
12+
13+
if (fs.existsSync(cacheFile)) {
814
try {
9-
// Perform Search
10-
const baseURL = process.env.NEXT_PUBLIC_SITE_URL || 'https://sfccdocs.com'
11-
const results = search(req.query.query, {
12-
limit: req.query.limit ? parseInt(req.query.limit, 10) : 100,
13-
offset: req.query.offset ? parseInt(req.query.offset, 10) : 0,
14-
})
15-
16-
// Loop through results
17-
results.map((result, index) => {
18-
// Add additional properties
19-
const parts = result.url ? result.url.split('#') : null
20-
const baseUri = parts[0]
21-
const anchor = parts.length > 1 ? `#${parts[1]}` : ''
22-
const deprecated = baseUri.startsWith('/deprecated/')
23-
const meta = getMeta(baseUri, deprecated)
24-
25-
result.deprecated = deprecated
26-
result.title = meta.title
27-
result.description = meta.description
28-
result.keywords = meta.nav?.alt ? meta.nav.alt.split(' › ') : null
29-
result.url = `${baseURL}${result.url}`
30-
result.embed = `${baseURL}${baseUri}?embed=true${anchor}`
31-
result.content = result.content ? result.content.split('. ')[0] : null
32-
33-
// Remove unneeded properties
34-
delete result.score
35-
36-
if (result.pageTitle) {
37-
delete result.pageTitle
38-
}
39-
40-
// Sort properties alphabetically for easier readability
41-
results[index] = Object.keys(result)
42-
.sort()
43-
.reduce((accumulator, key) => {
44-
accumulator[key] = result[key]
45-
46-
return accumulator
47-
}, {})
48-
})
49-
50-
// Return results
51-
res.status(200).json({ total: results.length, results, version: currentVersion })
15+
const cachedJson = fs.readFileSync(cacheFile, 'utf8')
16+
res.setHeader('Cache-Control', 's-maxage=86400')
17+
res.status(200).json(JSON.parse(cachedJson))
5218
} catch (error) {
5319
// Return error
5420
res.status(400).json({ error: error.message, trace: error.stack })
5521
}
56-
})
22+
} else {
23+
// Load Search Function
24+
import('@/markdoc/search.mjs').then(({ search }) => {
25+
try {
26+
// Perform Search
27+
const baseURL = process.env.NEXT_PUBLIC_SITE_URL || 'https://sfccdocs.com'
28+
const results = search(req.query.query, {
29+
limit: req.query.limit ? parseInt(req.query.limit, 10) : 100,
30+
offset: req.query.offset ? parseInt(req.query.offset, 10) : 0,
31+
})
32+
33+
// Loop through results
34+
results.map((result, index) => {
35+
// Add additional properties
36+
const parts = result.url ? result.url.split('#') : null
37+
const baseUri = parts[0]
38+
const anchor = parts.length > 1 ? `#${parts[1]}` : ''
39+
const deprecated = baseUri.startsWith('/deprecated/')
40+
const meta = getMeta(baseUri, deprecated)
41+
42+
result.deprecated = deprecated
43+
result.title = meta.title
44+
result.description = meta.description
45+
result.keywords = meta.nav?.alt ? meta.nav.alt.split(' › ') : null
46+
result.url = `${baseURL}${result.url}`
47+
result.embed = `${baseURL}${baseUri}?embed=true${anchor}`
48+
result.content = result.content ? result.content.split('. ')[0] : null
49+
50+
// Remove unneeded properties
51+
delete result.score
52+
53+
if (result.pageTitle) {
54+
delete result.pageTitle
55+
}
56+
57+
// Sort properties alphabetically for easier readability
58+
results[index] = Object.keys(result)
59+
.sort()
60+
.reduce((accumulator, key) => {
61+
accumulator[key] = result[key]
62+
63+
return accumulator
64+
}, {})
65+
})
66+
67+
const data = { total: results.length, results, version: currentVersion }
68+
fs.writeFileSync(cacheFile, JSON.stringify(data))
69+
70+
// Return results
71+
res.setHeader('Cache-Control', 's-maxage=86400')
72+
res.status(200).json(data)
73+
} catch (error) {
74+
// Return error
75+
res.status(400).json({ error: error.message, trace: error.stack })
76+
}
77+
})
78+
}
5779
}

0 commit comments

Comments
 (0)