This commit is contained in:
parent
588f60391a
commit
9d92a20872
7 changed files with 135 additions and 76 deletions
19
src/controllers/SearchController.js
Normal file
19
src/controllers/SearchController.js
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
export default class SearchController {
|
||||||
|
searchService
|
||||||
|
|
||||||
|
constructor(searchService) {
|
||||||
|
this.searchService = searchService
|
||||||
|
}
|
||||||
|
|
||||||
|
search = (req, res) => {
|
||||||
|
const query = req.params.query
|
||||||
|
const results = this.searchService.search(query)
|
||||||
|
if (!results) {
|
||||||
|
return res.status(404).json({
|
||||||
|
message: `No matches for query ${query}`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.json(results)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import express from "express"
|
import express from "express"
|
||||||
import entries from "./routes/entries.js"
|
import entries from "./routes/entries.js"
|
||||||
import tags from "./routes/tags.js"
|
import tags from "./routes/tags.js"
|
||||||
|
import search from "./routes/search.js"
|
||||||
import cors from "cors"
|
import cors from "cors"
|
||||||
import { validateApiKey } from "./middlewear/auth.js"
|
import { validateApiKey } from "./middlewear/auth.js"
|
||||||
import morgan from "morgan"
|
import morgan from "morgan"
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
|
|
||||||
const port = process.env.PORT || 4000
|
const port = process.env.PORT || 4000
|
||||||
|
|
@ -14,6 +16,7 @@ app.use(express.json())
|
||||||
app.use("/", validateApiKey)
|
app.use("/", validateApiKey)
|
||||||
app.use("/entries", entries)
|
app.use("/entries", entries)
|
||||||
app.use("/tags", tags)
|
app.use("/tags", tags)
|
||||||
|
app.use("/search", search)
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
console.info(`TB-INFO eolas-api running on NodeJS ${process.version}`)
|
console.info(`TB-INFO eolas-api running on NodeJS ${process.version}`)
|
||||||
|
|
|
||||||
12
src/routes/search.js
Normal file
12
src/routes/search.js
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import express from "express"
|
||||||
|
import SearchService from "../services/SearchService.js"
|
||||||
|
import SearchController from "../controllers/SearchController.js"
|
||||||
|
import database from "../db/connection.js"
|
||||||
|
|
||||||
|
const router = express.Router()
|
||||||
|
const searchService = new SearchService(database)
|
||||||
|
const searchController = new SearchController(searchService)
|
||||||
|
|
||||||
|
router.get("/:query", searchController.search)
|
||||||
|
|
||||||
|
export default router
|
||||||
|
|
@ -1,4 +1,10 @@
|
||||||
import { GET_ALL_ENTRIES, GET_ENTRY, GET_ENTRIES_FOR_TAG, GET_BACKLINKS_FOR_ENTRY, GET_OUTLINKS_FOR_ENTRY } from "../sql/entries.js"
|
import {
|
||||||
|
GET_ALL_ENTRIES,
|
||||||
|
GET_ENTRY,
|
||||||
|
GET_ENTRIES_FOR_TAG,
|
||||||
|
GET_BACKLINKS_FOR_ENTRY,
|
||||||
|
GET_OUTLINKS_FOR_ENTRY,
|
||||||
|
} from "../sql/entries.js"
|
||||||
|
|
||||||
export default class EntriesService {
|
export default class EntriesService {
|
||||||
database
|
database
|
||||||
|
|
@ -42,7 +48,7 @@ export default class EntriesService {
|
||||||
const list = sorted.flatMap((i) => i.source_entry_title)
|
const list = sorted.flatMap((i) => i.source_entry_title)
|
||||||
return {
|
return {
|
||||||
count: backlinks.length,
|
count: backlinks.length,
|
||||||
data: list
|
data: list,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,9 +58,8 @@ export default class EntriesService {
|
||||||
const list = sorted.flatMap((i) => i.target_entry_title)
|
const list = sorted.flatMap((i) => i.target_entry_title)
|
||||||
return {
|
return {
|
||||||
count: outlinks.length,
|
count: outlinks.length,
|
||||||
data: list
|
data: list,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_sortByTitle = (entries, fieldName) => {
|
_sortByTitle = (entries, fieldName) => {
|
||||||
|
|
|
||||||
17
src/services/SearchService.js
Normal file
17
src/services/SearchService.js
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { SEARCH } from "../sql/search.js"
|
||||||
|
|
||||||
|
export default class SearchService {
|
||||||
|
database
|
||||||
|
|
||||||
|
constructor(database) {
|
||||||
|
this.database = database
|
||||||
|
}
|
||||||
|
|
||||||
|
search = (query) => {
|
||||||
|
const results = this.database.prepare(SEARCH).all(query.trim())
|
||||||
|
return {
|
||||||
|
count: results.length,
|
||||||
|
data: results,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/sql/search.js
Normal file
3
src/sql/search.js
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
const SEARCH = `SELECT title as entry, snippet(entries_fts, 1, '<mark>', '</mark>', '...', 24) as excerpt FROM entries_fts WHERE entries_fts MATCH ? ORDER BY rank LIMIT 25`
|
||||||
|
|
||||||
|
export { SEARCH }
|
||||||
Loading…
Add table
Reference in a new issue