블로그 express + mongodb 로 만들기

블로그 만들기(11) - 검색 기능

Uijeong 2023. 12. 29. 12:09

검색기능 만들기전에

저번에 댓글기능을 만들었는데

게시글을 삭제하면, 댓글도 보이지는 않지만 comment collection에 그대로 남아있을것 같습니다.

 

그래서 게시글을 삭제할 경우, 댓글도 삭제되도록 기능 수정을 좀 했습니다.

 

댓글 작성할때 comment 컬렉션에 postId : req.params.id 저장해뒀기 때문에

 

글 삭제할때 deleteMany()를 이용해서 postId : req.params.id 인 comment들 전부 삭제해주면

게시글을 삭제할때 댓글도 삭제될것 같네요

await db.collection('comment').deleteMany({ postId : req.params.id });

/delete/:id 요청에서 이거 하나 추가해주면 끝인듯 합니다.

 

이제 검색기능을 만들어 볼겁니다.

 

밑에 페이지네이션 바 밑에 input 하나 만들고

입력하면 입력된 내용과 일치하는 게시물들을 보여주면 될것같습니다.

 

검색했을때 찾으려는 내용이랑 db저장된 내용이 일치하는 게시물을 보여주면 될것같습니다.

 

먼저 input을 만들고

 

검색눌렀을때 /search로 get요청 해주고 value 값이랑 db에 저장된거랑 비교해주면 될듯

<div>
        <form method="GET", action="/search">
            <input name="title"><button type="submit">검색</button>
        </form>
    </div>

제목 일치하는거 db에서 가져오려면

const searchResult = await db.collection('post').find({title : req.query.title}).toArray()

 

1. post 컬렉션에 저장된 title이랑 일치하는 경우

2. 배열화해서 searchResult 변수로 저장

3. 저장된 정보로 main.ejs 페이지에서 html 생성

 

이런식의 로직으로 가면 될듯

근데 이 searchResult 의 결과를 다른 get요청에서 쓰고싶어서

session 활용해서 데이터르 임시저장 하기로 했음

req.session.searchResult = searchResult;

 

이렇게 해주면 다른 get요청 에서도 searchResult 사용할수 있을것 같음

마지막으로 redirect 해주면 될것같음

res.redirect('/main/0')

 

이제 main페이지 요청에서

조건문을 이용할건데

req.session.searchResult의 값이 존재하면 result는

result = req.session.searchResult;

 

req.session.searchResult가 존재하지 않으면 result는 기존 로직을 따라가면 될듯

if (req.session.searchResult) {
            result = req.session.searchResult;
        } else {
            const pageSize = 8;
            const totalCount = await db.collection('post').countDocuments();
            totalPages = Math.ceil(totalCount / pageSize);

            pageId = parseInt(req.params.id) || 1;
            const skip = (pageId - 1) * pageSize;

            result = await db.collection('post')
                .find()
                .skip(skip)
                .limit(pageSize)
                .toArray();
        }

 

검색기능이 잘 동작하는지 확인해보면

잘 검색이 되는것 같이 보이는데

 

문제가 발생함, 홈페이지를 눌러도 계속 검색된 결과만 뜸

왜이런지 생각해 보니깐

조건문을  req.session.searchResult가 존재할 경우

result = req.session.searchResult; 이여서, session에 값을 계속 저장하고 있어서 이렇게 되는듯

 

조건을 추가해줘야 할듯

검색 버튼을 눌렀을 경우에만 검색 결과를 보여주고 싶음

그러면 검색 버튼을 눌렀을때

즉 /search api가 발생했을경우 && req.session.searchResult 이 조건문을 만들면 될듯

 

그럼 검색 버튼을 누를 경우 true 값을 보내주고

true 값이 존재할경우 && req.session.searchResult 값이 참일경우만 검색 결과를 result 에 저장해주면 될듯

 

그래서 qeury문 이용해서 데이터 보냄

res.redirect('/main/0?search=true')

 

이러면 검색 버튼을 누르면 search=true 값을 보내줄듯

const isSearchMode = req.query.search;
        if (isSearchMode && req.session.searchResult) {
            result = req.session.searchResult;
        } else {
            const pageSize = 8;
            const totalCount = await db.collection('post').countDocuments();
            totalPages = Math.ceil(totalCount / pageSize);

            pageId = parseInt(req.params.id) || 1;
            const skip = (pageId - 1) * pageSize;

            result = await db.collection('post')
                .find()
                .skip(skip)
                .limit(pageSize)
                .toArray();
        }

 

이런식으로 조건문을 평가하면

검색버튼을 눌렀을때

검색된 게시물을 잘 보여줄것 같음

 

검색기능을 살펴보는데

검색은 잘되는데 문장이 완전히 일치해야만 검색이 됨

이러면 사용할때 좀 불편할것 같은데

 

원래 보통 검색기능 사용하는거 보면

단어 단위로 찾아서 검색하게 해주는게 대부분인데

 

이런식으로 찾으려면 너무 불친절한듯

그래서 조금더 편하게 검색가능하도록 바꿔보겠음.

 

검색할때, 정규식을 이용해서 검색하면 될것같아서 그렇게해봄

        const searchQuery = new RegExp(req.query.title, 'i');

        const searchResult = await db.collection('post').find({ title: searchQuery }).toArray();

 

이렇게 해주면 정규표현식 거쳐서 검색 가능할거같음

 

테스트 해보면

 

단어단위로 검색해도 잘 검색되는 모습입니다.

 

이제 게시판으로 구현 가능한 기능들은 거의다 해본듯 합니다.

정말 간단하게 기능구현 정도만 해본것 같네요.

 

검색기능은 여기까지 입니다.