검색어 자동완성을 위해, 유저가 인풋태그에 한 글자만 입력한 경우, 서버는 이 때 클라이언트로부터 요청을 받습니다.
서버는 query로 받은 한 글자가 포함된 모든 레코드를 탐색하고, 이 때의 결과를 응답합니다.
클라이언트는 응답받은 객체를 유저에게 자동완성기능으로 사용할 수 있습니다.
input
tag에 글자를 타이핑한다.위와 같은 순서로 진행됩니다.
...
const [word, setWord] = useState('');
useEffect(() => {
const getAutoComp = async (word) => {
if (word !== '') {
let getResult = await axios.get(`${url}/word?query=${word}`);
console.log(getResult.data.data);
}
};
getAutoComp(word);
}, [word]);
...
return (
...
<input
id='reqInput'
onChange={(event) => setWord(event.target.value)}
value={word}
></input>
...
);
인풋 태그에 onChange
를 할당하고, 그 때 이벤트의 value
를 word State에 업데이트합니다.
그렇게되면, useEffect
의 종속 배열인 word가 업데이트되면서 getAutoComp
함수가 실행됩니다.
const { word } = require('../../models');
module.exports = {
get: async (req, res) => {
const sequelize = require('sequelize');
const Op = sequelize.Op;
const wordSplit = req.query.query;
const authCompWords = await word.findAll({
where: { wordName: { [Op.like]: '%' + wordSplit + '%' } },
});
const returnData = authCompWords.map((el) => el.wordName);
res.status(200).json({
data: returnData,
});
},
};
클라이언트의 요청을 처리하는 서버는 간단합니다. query
로 받아온 문자열을 DB에서 탐색하기만 하면 됩니다.
이 때, 사용되는 것이 Sequelize.Op
입니다.
Sequelize.Op
는 Sequelize가 제공하는 연산자입니다.
제공하는 연산자는 and, or, equal, like
등 다양합니다.
유사검색을 위해 like
연산자를 사용했고, 사용 방법은 위 코드처럼 간단합니다.
DB에서 검색을 원하는 테이블에서 검색을 원하는 필드의 값을 탐색할 때, Op.like
조건절을 추가하는 것입니다.
위 코드로 보면, wordSplit
이라는 문자열 앞 뒤에 %
를 붙였습니다.
%
가 붙은 위치에 따라 탐색 결과가 달라집니다.
'%' + wordSplit + '%'
wordSplit
문자열이 포함된 모든 레코드를 가져옵니다.'%' + wordSplit
wordSplit
앞에 어떤 문자열이 붙어도 탐색합니다. 그러나, wordSplit
뒤에 문자열이 존재한다면, 탐색하지 않습니다.wordSplit + '%'
wordSplit
뒤에 어떤 문자열이 붙어도 탐색합니다. 그러나, wordSplit
앞에 문자열이 존재한다면, 탐색하지 않습니다.이제 실행 결과를 보면 다음과 같습니다.
고
라고 인풋 태그에 입력했을 때, 서버로부터 받아온 결과입니다.
고
가 포함된 모든 단어를 가져온 모습입니다.
고
라고 입력했을 때, 고
앞에 붙은 문자열은 어떤 문자열이든 상관없이 탐색한다는 것을 알 수 있습니다.
그러나, 고
뒤에 어떤 문자열이 붙는 경우, 탐색하지 않습니다.
한 마디로, 고
로 끝나는 모든 문자열을 탐색합니다.
고
라고 입력했을 때, 고
뒤에 붙은 문자열은 상관없이, 고
로 시작하는 모든 문자열을 탐색합니다.
단, 고
앞에 어떤 문자열이 포함되어있다면, 탐색하지 않습니다.
유사 검색을 사용하면 검색어 자동완성 기능을 구현할 수 있습니다.
그러나, 이제 여기서 생각해봐야할 문제가 생깁니다.
유저가 input
태그에 어떤 문자열을 타이핑할 때마다, 서버로 요청이 가는 것을 알 수 있습니다.
예를 들어, 고양이
라고 input
태그에 타이핑을 했을 때, 나타나는 응답입니다.
onChange
함수가 8번 실행되었다는 뜻이며, 이는 즉 서버로 요청이 8번이 간 것을 의미합니다.
이렇게 되면, 웹 앱을 배포했을 때, 유저가 타이핑을 할 때마다 서버로 요청이 들어오므로, 서버에 부담이 됩니다.
이 때, 서버의 부담을 줄이고 조금 더 효율적인 검색을 위한 프로그래밍 방법론이 있습니다.
이에 대해 공부해서 포스팅해보겠습니다. 긴 글 읽어주셔서 감사드립니다!