공개 검색 인덱스 추가
This commit is contained in:
@@ -1721,7 +1721,6 @@ export const listAdminTags = async (options = {}) => listTags(options)
|
||||
const SEARCH_TAG_LIMIT = 12
|
||||
const SEARCH_POST_LIMIT = 12
|
||||
const SEARCH_PAGE_LIMIT = 8
|
||||
const SEARCH_POST_CANDIDATE_LIMIT = 48
|
||||
|
||||
/**
|
||||
* 공개 검색어를 비교 가능한 문자열로 정리한다.
|
||||
@@ -1756,11 +1755,15 @@ export const searchPublicContent = async (rawQuery) => {
|
||||
if (!q) {
|
||||
return { tags: [], posts: [], pages: [] }
|
||||
}
|
||||
const searchTextQuery = normalizeSearchContent(q).toLowerCase()
|
||||
if (!searchTextQuery) {
|
||||
return { tags: [], posts: [], pages: [] }
|
||||
}
|
||||
|
||||
const sql = getPostgresClient()
|
||||
|
||||
if (!sql) {
|
||||
const needle = q.toLowerCase()
|
||||
const needle = searchTextQuery
|
||||
const posts = getSamplePosts()
|
||||
.filter((post) => {
|
||||
const hay = normalizeSearchContent(`${post.title}\n${post.excerpt || ''}\n${post.content || ''}`).toLowerCase()
|
||||
@@ -1796,58 +1799,67 @@ export const searchPublicContent = async (rawQuery) => {
|
||||
|
||||
return { tags, posts, pages }
|
||||
}
|
||||
const searchPattern = `%${searchTextQuery}%`
|
||||
const searchPrefixPattern = `${searchTextQuery}%`
|
||||
|
||||
const tagRows = await sql`
|
||||
SELECT name, slug
|
||||
FROM tags
|
||||
WHERE
|
||||
position(lower(${q}) in lower(name)) > 0
|
||||
OR position(lower(${q}) in lower(slug)) > 0
|
||||
ORDER BY sort_order ASC, name ASC
|
||||
lower(name) LIKE ${searchPattern}
|
||||
OR lower(slug) LIKE ${searchPattern}
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN lower(name) = ${searchTextQuery} OR lower(slug) = ${searchTextQuery} THEN 0
|
||||
WHEN lower(name) LIKE ${searchPrefixPattern} OR lower(slug) LIKE ${searchPrefixPattern} THEN 1
|
||||
ELSE 2
|
||||
END,
|
||||
sort_order ASC,
|
||||
name ASC
|
||||
LIMIT ${SEARCH_TAG_LIMIT}
|
||||
`
|
||||
|
||||
const postRows = await sql`
|
||||
SELECT posts.slug, posts.title, posts.excerpt, posts.content
|
||||
SELECT posts.slug, posts.title, posts.excerpt
|
||||
FROM posts
|
||||
WHERE posts.status = 'published'
|
||||
AND (posts.published_at IS NULL OR posts.published_at <= now())
|
||||
AND (
|
||||
position(lower(${q}) in lower(posts.title)) > 0
|
||||
OR position(lower(${q}) in lower(coalesce(posts.excerpt, ''))) > 0
|
||||
OR position(lower(${q}) in lower(posts.content)) > 0
|
||||
)
|
||||
ORDER BY posts.published_at DESC NULLS LAST, posts.created_at DESC
|
||||
LIMIT ${SEARCH_POST_CANDIDATE_LIMIT}
|
||||
AND posts.search_text LIKE ${searchPattern}
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN lower(posts.title) = ${searchTextQuery} THEN 0
|
||||
WHEN lower(posts.title) LIKE ${searchPrefixPattern} THEN 1
|
||||
WHEN lower(coalesce(posts.excerpt, '')) LIKE ${searchPrefixPattern} THEN 2
|
||||
ELSE 3
|
||||
END,
|
||||
posts.published_at DESC NULLS LAST,
|
||||
posts.created_at DESC
|
||||
LIMIT ${SEARCH_POST_LIMIT}
|
||||
`
|
||||
|
||||
const pageRows = await sql`
|
||||
SELECT slug, title, content, listing_section, listing_title, listing_description
|
||||
SELECT slug, title, listing_section, listing_title, listing_description
|
||||
FROM pages
|
||||
WHERE status = 'published'
|
||||
AND is_listed = true
|
||||
AND (
|
||||
position(lower(${q}) in lower(title)) > 0
|
||||
OR position(lower(${q}) in lower(coalesce(listing_section, ''))) > 0
|
||||
OR position(lower(${q}) in lower(coalesce(listing_title, ''))) > 0
|
||||
OR position(lower(${q}) in lower(coalesce(listing_description, ''))) > 0
|
||||
OR position(lower(${q}) in lower(content)) > 0
|
||||
)
|
||||
ORDER BY is_featured DESC, listing_section ASC, listing_sort_order ASC, updated_at DESC
|
||||
AND search_text LIKE ${searchPattern}
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN lower(coalesce(listing_title, title)) = ${searchTextQuery} THEN 0
|
||||
WHEN lower(coalesce(listing_title, title)) LIKE ${searchPrefixPattern} THEN 1
|
||||
WHEN lower(coalesce(listing_description, '')) LIKE ${searchPrefixPattern} THEN 2
|
||||
ELSE 3
|
||||
END,
|
||||
is_featured DESC,
|
||||
listing_section ASC,
|
||||
listing_sort_order ASC,
|
||||
updated_at DESC
|
||||
LIMIT ${SEARCH_PAGE_LIMIT}
|
||||
`
|
||||
|
||||
const needle = q.toLowerCase()
|
||||
const posts = postRows
|
||||
.filter((row) => {
|
||||
const hay = normalizeSearchContent(`${row.title}\n${row.excerpt || ''}\n${row.content || ''}`).toLowerCase()
|
||||
return hay.includes(needle)
|
||||
})
|
||||
.slice(0, SEARCH_POST_LIMIT)
|
||||
|
||||
return {
|
||||
tags: tagRows.map((row) => ({ name: row.name, slug: row.slug })),
|
||||
posts: posts.map((row) => ({
|
||||
posts: postRows.map((row) => ({
|
||||
slug: row.slug,
|
||||
title: row.title,
|
||||
excerpt: row.excerpt || ''
|
||||
|
||||
Reference in New Issue
Block a user