본문 바로가기
Server/Node.js

검색기능 만들기(3) - Search Index

by print_soo 2023. 9. 9.

해당 글은 이전 글들의 작업을 이어서 진행되고 있는 글입니다.

 

 

app.get('/search', (request, response) => {
    db.collection('post').find({ $text: {$search: request.query.value} }).toArray(function (error, result) {
        response.render('search.ejs', { keyword: result })
    });
})

 

이전에 만들었던 위의 코드는 한국어와 같이 조사가 많이 붙는 언어는 구분하기 못한다. 

따라서 우리는 Search Index를 이용해서 탐색을 해야한다 .

 

1. 이전에 만들었던 Index 삭제하기

 

indexes로 들어가서 만들었던 index를 삭제한다. 

 

 

2. Search Index 생성하기

 

create search index
visual editor
lucene.Korean으로 변경하기
최종으로 만들기

 

 

 

3. 코드 수정해보기

이번에는 find 함수 대신 aggregate 함수를 사용해보려고한다.

 

aggregate 함수의 특징

  • Array를 입력할 수 있다. 
  • 검색 조건을 달 수 있다. 

 

app.get('/search', (request, response) => {
    var searchRequirement = [
        {
            $search: {
                index: 'titleSearch', //만든 인덱스 이ㅁ
                text: {
                    query: request.query.value,
                    path: 'title' //찾고 싶은 데이터 명
                }
            }
        }
    ]; //검색 조건
    db.collection('post').aggregate(searchRequirement).toArray(function (error, result) {
        response.render('search.ejs', { keyword: result })
    });
})

 

 

이제 조금 더 업그레이드해서 해당 데이터를 찾고 정렬까지 해주는 코드를 만들어보자.

 

app.get('/search', (request, response) => {
    var searchRequirement = [
        {
            $search: {
                index: 'titleSearch', //만든 인덱스 이ㅁ
                text: {
                    query: request.query.value,
                    path: 'title' //찾고 싶은 데이터 명
                }
            }
        },
        { $sort : { _id : -1} } //_id를 오름차순(1)으로 정리 (내림차순은 -1)
    ]; //검색 조건
    db.collection('post').aggregate(searchRequirement).toArray(function (error, result) {
        response.render('search.ejs', { keyword: result })
    });
})

 

 

 

만약 데이터를 필터링해서 찾고 싶다면 어떻게 해야할까? $project라는 키워드를 사용하면 된다.

 

app.get('/search', (request, response) => {
    var searchRequirement = [
        {
            $search: {
                index: 'titleSearch', //만든 인덱스 이ㅁ
                text: {
                    query: request.query.value,
                    path: 'title' //찾고 싶은 데이터 명
                }
            }
        },
        // { $sort : { _id : 1} } //_id를 오름차순으로 정리 (내림차순은 -1)
        { $project : { title: 1, _id: 0, score: {$meta: "searchScroe"} }}
    ]; //검색 조건
    db.collection('post').aggregate(searchRequirement).toArray(function (error, result) {
        response.render('search.ejs', { keyword: result })
    });
})

$project라는 키워드는 가져올 데이터는 1을 부여하고 가져오지 않을 데이터는 0을 부여한다. 

또한 searchScore라는 것을 저장하지 않고도 가져올 수 있는데 이건 검색한 키워드와 검색된 데이터의 연관성을 나타내는 점수이다. (높을 수록 연관성이 있는 것)