본문 바로가기
Node.js

Node.js 검색기능 구현하기

by Zih0 2021. 4. 23.

유사검색

검색어를 완전히 똑같게 입력하지 않아도 일부 내용이 같으면 검색하는 것을 말합니다.

SQL 문법에 like 문법이 있어 Sequelize Docs에서 해당 문법을 확인할 수 있었습니다.

sequelize의 where 부분에 아래와 같이 Op.like를 이용하면 됩니다.

const { Op } = require("sequelize");

    {
                where: {
                        { brand: { [Op.like]: `%${searchText}%` } },
                },
    }

진행중인 프로젝트에서 상품 검색을 위한 검색 기능이라, 브랜드나 상품명을 검색했을 때 검색결과가 나오길 바랬습니다.

Sequelize에선 or 문법도 Op에서 제공하고 있더군요.

아래와 같이 [Op.or] 을 이용해주었습니다.

{
                where: {
                    [Op.or]: [
                        { brand: { [Op.like]: `%${searchText}%` } },
                        { name: { [Op.like]: `%${searchText}%` } },
                    ],
                },
            }

문제점

이렇게 유사 검색을 쉽게만 생각했는데, 띄어쓰기가 문제였습니다.

CASE1

DB에는 '가나다라'로 저장되어 있고, '가나 다라'로 검색한 경우

CASE2

DB에는 '가나 다라'로 저장되어 있고, '가나다라'로 검색한 경우

CASE1 해결법

검색어를 받아올 때, 자바스크립트의 replace 문법을 사용했습니다.

let searchText = req.params.searchText;
searchText = searchText.replace(" ", "%");

공백을 %로 바꿔주어 간단하게 해결했습니다.

CASE2 해결법

문제는 DB에 저장된 값의 띄어쓰기 였습니다.

일단 SQL 쿼리로 해당 문제를 어떻게 해결해야할지 짜봤습니다. SQL에도 replace 문법이 있는걸, 해결하면서 알게 됐네요.

select * from fragrances where replace(kr_brand," ","") like "%산타%마리아%" or replace(brand," ","") like "%산타%마리아%" 

그 후에 Sequelize의 findAll을 통해 이 쿼리를 적용시키려고 했는데, 공식문서를 찾아봐도 원하는 답이 없었습니다.

Sequelize에서 Raw Query로 검색하는 걸 지원하기에, 해당 함수는 Raw Query로 구현하기로 했습니다.

const { QueryTypes } = require("sequelize");

searchText = `%${searchText.replace(/ /gi, "%")}%`;
const query =
            'select * from fragrances where replace(kr_brand," ","") like :searchText or replace(brand," ","") like :searchText';
        try {
            const searchList = await sequelize.query(query, {
                replacements: { searchText: searchText },
                type: QueryTypes.SELECT,
                raw: true,
            });

QueryTypes를 추가적으로 import해주고,

동적으로 들어갈 검색어는 :searchText 처럼 검색어에 :(콜론)을 붙이고, replacements 에서 변수를 지정해주면 됩니다.

댓글