개발/NestJS
ElasticSearch 사용하지 않고 Search API 작성
8시20분
2021. 9. 10. 08:20
ElasticSearch를 사용하지 않고, 단어 기반의 통합 검색 기능을 추가해야하는 일이 생겼다.
통합검색 API를 구축할 때, 맨처음에는 다음과 같이 @Body 를 사용하여 body안에 {word: 단어}를 포함시켜 API를 호출하는 방식으로 설계하였다.
// @Body를 사용하였을 때
@Get('')
search(@Body(){word: string}){
return this.service.search(word);
}
위의 코드처럼 작성하고 테스트 했을 때, word를 undefined로 호출시 백엔드로 전달이 되지않는 이슈가 있었다.
구글은 어떤 방식으로 하는지 궁금해서 구글에 검색을 해보고 url을 중점적으로 확인하였다.
구글의 검색 URL을 보고 @Query를 사용하여 API의 url뒤에 ?를 붙여서 'http://localhost?word={검색하려는 단어}'와 같이 구성하였다.
@Get('?')
async search(@Query('word') word: string) {
const searchWithUser = await this.userService.findByUserName(word);
const searchWithTag = await this.tagService.findByWord(word);
const searchWithStoryTitle = await this.storyService.findByWord(word);
const searchWithProductTitle = await this.productService.findByWord(word);
const SearchedTagStory = await this.tagStoryService.findByTagId(
searchWithTag,
);
const findStoryWithStoryId = await this.storyService.findByStoryId(
searchWithStoryTitle,
);
const findStoryWithProductId = await this.storyService.findByProductId(
searchWithProductTitle,
);
const findStoryWithTagId = await this.storyService.findByTagStoryIds(
SearchedTagStory,
);
if (
!searchWithUser &&
!findStoryWithStoryId &&
!findStoryWithProductId &&
!findStoryWithTagId
) {
return null;
} else {
const result = [
...searchWithUser,
...findStoryWithStoryId,
...findStoryWithProductId,
...findStoryWithTagId,
];
const SetResult = new Set(result);
return SetResult;
}
API 작동 방식은 어떻게보면 단순무식하게 보일 수도 있는데 @Query로 입력받은 단어로 관련 테이블 4개에 쿼리를 날려서 받아온 정보를 Set( )을 통해 중복 제거하고 리턴하는 것이다.