자꾸 안해본 걸 하려고 할 때마다 자신감이 떨어진다.
하지만 늘 그렇듯 막상 해보면 별거 아닐 때가 많다. 이번에도 비슷한 것 같다.
좋은 레퍼런스를 찾았고 참고를 하면서 나의 케이스에 맞게 적용해야해서 막히거나 모르겠을 때, 검색하면 할 수 있음을 계속 경험하고 있어서 다행이고 좋다.
결국 해낸 케이스에 대해 정리해보겠다.
독자에게 보여지는 글은 가급적 SSR로 보여주고 싶었다. 좀 더 빠른 렌더링, SEO 를 위해서이다.
그런데 작성하다보니 searchParams가 필요했는데 나는 nextjs에 능숙하지 않아서 useSearchParams를 사용해야만 하는 줄 알았다. 그래도 방법이 있나 하고 구글링을 해봤다.
나와 같은 고민을 하는 사람들이 많았고 결국 비교적 빠르고 간단히 해결방법을 찾았다. nextjs searchparams server component
라고 검색해봤고 거기에는 nextjs 공식문서를 레퍼런스로 달면서 page.js에서 searchParams를 가져와 사용하는 예시를 보여주었다.
어쩐지 그 전에 강의를 들으면서 searchParams를 props로 받았지만 내려주는 곳이 없어 의아하게 생각하며 넘어간 바로 그 searchParams 였다. (심지어 난 봤고 유심히 코드를 까보았음에도 잘 몰라서 그냥 넘어간 것 이였다.)
바로 내 프로젝트에서 console.log를 찍어보니 내가 원하던 값이 잘 나왔다.
얼마나 잘 알려져있는 parameter인지는 모르겠으나 꽤나 유용히 사용될 것 같다. 스스로 문제를 해결하는 좋은 경험을 한 번 더 쌓을 수 있어서 기뻤다.
‘그래도 방법이 있나 찾아보는 것’ 이런 마음가짐이 중요한 것 같다.
mongoDB와 한 번도 해본 적이 없는 검색 기능을 넣어줘야 해서 두렵고 걱정이 많았다.
하지만 해냈다. 방법은 심플하다. 그냥 할 수 있는 방법으로 시작하는 것이다.
일단 내가 구현하려는 스펙과 유사한 레퍼런스를 찾았다. 유튜브 강의가 잘 맞아서 한 번 쭉 따라 구현을 해보았다. 내 시야에서는 잘 몰랐던 후속 처리(?) 같은 것도 알려주어서 좋았다. (이를테면 refresh할 때, searchParams가 날아갈 수 있다는 것. 그리고 이에대한 처리 방법을 알려주었다.)
그리고 다시 내 프로젝트에 맞게 구현을 해보았다. 그러던 중 나만의 케이스에 맞게 코드를 녹여야 하는 부분들이 발생했다.
아래의 코드가 그런 성향이 강했던 코드다. 내 조건은 title과 content.text에서만 검색할 내용을 조회해야하는 것이였다. mongoDB랑 연결되는 부분이기 때문에 공부할 리소스를 따로 더 투자하기 보다는 Chat GPT에게 상세히 오더를 내려서 구현 방법을 찾아냈다. 확인해보니 내가 원하는 방법으로 잘 구현이 되었다. (동작 방식도 알아두어서 모르는 코드라고 생각하지 않는다.)
export const GET = async (request: NextRequest) => {
const searchTerm = request.nextUrl.searchParams.get('searchTerm')
await connectMongoDB()
const searchCondition = {
$or: [
{ title: { $regex: searchTerm, $options: 'i' } },
{ 'content.text': { $regex: searchTerm, $options: 'i' } },
],
}
const articles = searchTerm
? await Article.find(searchCondition)
: await Article.find()
return NextResponse.json({ articles })
}
searchParams는 nextjs에 내장된 방식으로 구현해야 했기 때문에 다른 코드를 참고하여 구현할 수 있었다.
이렇게 차근차근 하나하나 해결해나가다보니 어느 새, 검색 기능이 구현되어 있었다.
아직 주니어라 그런지 매우 기뻤다. :>
이렇게 계속 성공 경험을 쌓다보면 어느 새, 모르는 문제가 와도 두려워하기 보다는 하나씩 해결해 나가며 더 큰 성취를 얻을 수 있으리라 생각한다. 그때까지 묵묵히 지금 내가 할 수 있는 것을 해나가도록 하자.
대부분 chatGPT만을 통해 검색을 했는데 그 이유는 mongoose를 아주 많이 이해하지 못한 상태이기 때문이다. (온전히 이해하긴 시간이 없었다.)
무수히 많은 검색을 해도 원하는 결과가 나오지를 않았다.
title만 또는 content만 검색이 되었다.
처음에는 내 백엔드 로직 (schema, interface 등)을 알려줬다. 그리고 내 요구 사항을 말했다.
답이 나오지 않자 까다로운 내 요청 사항이 문제라고 생각했다. (요청 사항 title과 content를 검색가능하게 하면서도 return 할 때는 content의 _id만 달라)
계속해서 던져주는 답은 대부분 title만 검색 되었다.
mongoose 문법을 제대로 알지 못했기 때문에 너무 답답하고 막막했다. 뭘 고쳐야할지 모르겠었다.
(참고로 중간에 mongoose 공식문서를 봤는데도 모르겠더라..)
그렇게 질문과 답이 도돌이표를 돌던 중에 질문을 바꾸어 보았다.
계속 title만 검색이 되었으니 이번에는 ‘content만 검색해서 일치되는 값을 반환하게 해줘’라는 질문을 던졌고 그러자 원하는 대로 이번엔 title이 아니라 content에서 원하는 값이 검색이 되었다.
// chatGPT에서 알려준 값
export const GET = async (request: NextRequest) => {
const searchTerm = request.nextUrl.searchParams.get('searchTerm')
console.log('searchTerm', searchTerm)
await connectMongoDB()
const articles = await Article.aggregate([
{
$lookup: {
from: 'articlecontents',
localField: 'content',
foreignField: '_id',
as: 'content',
},
},
{
$unwind: {
path: '$content',
preserveNullAndEmptyArrays: true,
},
},
{
$match: {
'content.text': { $regex: searchTerm, $options: 'i' },
// 이 문법으로 content만 검색이 되었다.
},
},
{
$project: {
title: 1,
content: 1,
createdAt: 1,
updatedAt: 1,
__v: 1,
},
},
])
console.log('articles:', articles)
return NextResponse.json({ articles })
}
그간 $match라는 문법을 통해 조건을 걸어주던 걸 알았던 나는 그간 title만 검색되게 하던 조건을 함께 넣어주어 봤다.
// 수정해준 코드
const searchCondition = {
$or: [
{ title: { $regex: searchTerm, $options: 'i' } },
{ 'content.text': { $regex: searchTerm, $options: 'i' } },
],
}
...생략
{
$match: searchCondition
},
...생략
그러자 원하는 대로 동작했다.
얻은 점
소감
어제 몇 시간을 이 버그로 끙끙 앓았기 때문에 좀 뿌듯했다.
조금 아쉬운 점은 mongoose라는 문법을 제대로 아는 상태가 아니라 정확히는 이해하진 못한 상태다.
다행히 GPT한테 해결한 코드를 해석해달라고 해서 어떤 로직이 수행되고 있는지는 알고 있다.
시간 관계상 더 깊이 파는 건 어렵겠지만 플젝 하면서 조금씩이라도 알아두면 좋을 것 같다!
수고했다 내 자신 !!