AWS OpenSearch를 Next.js 앱에 통합하여 고성능 검색 기능 구현하기
2024-10-29 22:32:35AWS OpenSearch를 Next.js에 통합하여 검색 기능을 구현하기
현대의 웹 애플리케이션은 사용자의 요구를 충족시키기 위해 점점 더 고급 검색 기능을 필요로 합니다. 이러한 요구에 부응하기 위한 좋은 방법 중 하나는 AWS OpenSearch를 사용하는 것입니다. 이 포스트에서는 AWS OpenSearch를 Next.js 앱에 통합하여 빠르고 확장 가능한 검색 기능을 구현하는 방법을 단계별로 설명합니다.
목차
- AWS OpenSearch란 무엇인가?
- 시작하기 전에 필요한 것들
- AWS OpenSearch 설정
- Next.js에서 OpenSearch 클라이언트 구성하기
- OpenSearch 인덱스 생성하기
- OpenSearch 인덱스에 데이터 추가하기
- 검색 기능 구현하기
- UI에 검색 기능 통합하기
- OpenSearch 성능 최적화
- 참고자료 및 추가 리소스
AWS OpenSearch란?
AWS OpenSearch는 복잡한 검색 및 분석 기능을 제공하는 서비스로, 이전에는 ElasticSearch로 알려져 있었습니다. 이를 통해 쉽고 빠르게 데이터를 검색하고 분석할 수 있습니다.
시작하기 전에 필요한 것들
프로젝트를 진행하기 전 다음의 준비물이 필요합니다:
- AWS 계정: OpenSearch 서비스에 접근할 수 있어야 합니다.
- Next.js 프로젝트: 기본 프로젝트가 설정되어 있어야 합니다.
- 기본 REST API 및 JSON사용: 해당 개념에 대한 기초 지식을 가지고 있어야 합니다.
AWS OpenSearch 설정
- AWS Management Console에 접속합니다.
- OpenSearch Service로 이동 후, Create Domain 버튼을 클릭합니다.
- 다양한 설정을 통해 다음과 같이 구성합니다:
- 도메인 이름: 고유한 OpenSearch 클러스터 이름을 설정합니다.
- 인스턴스 유형: 개발용으로 적절한 인스턴스를 선택합니다(예: t2.small).
- 접근 정책: Next.js 앱 IP 또는 특정 AWS 역할에서 접근할 수 있도록 설정합니다.
설정이 완료되면 Create를 클릭하고 도메인이 초기화될 때까지 기다립니다.
Next.js에서 OpenSearch 클라이언트 구성하기
AWS OpenSearch가 준비되었으면, AWS SDK와 @opensearch-project/opensearch 패키지를 사용하여 연결을 설정할 수 있습니다.
-
다음 명령을 사용하여 필요한 패키지를 설치합니다:
npm install aws-sdk @opensearch-project/opensearch -
lib/opensearchClient.js파일을 생성하여 클라이언트를 초기화하고 설정합니다.import AWS from 'aws-sdk'; import { Client } from '@opensearch-project/opensearch'; const region = 'your-aws-region'; const domainEndpoint = 'https://your-opensearch-domain-endpoint'; AWS.config.update({ accessKeyId: process.env.AWS_ACCESS_KEY, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, region, }); export const opensearchClient = new Client({ node: domainEndpoint, Connection: require('@opensearch-project/opensearch/aws'), awsConfig: new AWS.Config(), }); -
AWS_ACCESS_KEY와AWS_SECRET_ACCESS_KEY를.env.local파일에 추가합니다.AWS_ACCESS_KEY=your-access-key AWS_SECRET_ACCESS_KEY=your-secret-access-key
OpenSearch 인덱스 생성하기
OpenSearch에 데이터를 추가하기 위해서는 먼저 해당 데이터를 저장할 인덱스를 생성해야 합니다.
-
pages/api/createIndex.js파일에 인덱스 생성을 위한 API 라우트를 정의합니다:import { opensearchClient } from '../../lib/opensearchClient'; export default async function handler(req, res) { try { await opensearchClient.indices.create({ index: 'products', body: { mappings: { properties: { name: { type: 'text' }, description: { type: 'text' }, price: { type: 'float' }, }, }, }, }); res.status(200).json({ message: 'Index created successfully' }); } catch (error) { console.error(error); res.status(500).json({ error: 'Error creating index' }); } }
OpenSearch 인덱스에 데이터 추가하기
생성한 인덱스에 도큐멘트를 추가하여 검색이 가능하도록 설정합니다.
-
pages/api/addDocument.js파일에 도큐먼트 추가를 위한 API 라우트를 정의합니다:import { opensearchClient } from '../../lib/opensearchClient'; export default async function handler(req, res) { const { name, description, price } = req.body; try { await opensearchClient.index({ index: 'products', body: { name, description, price }, }); res.status(200).json({ message: 'Document added successfully' }); } catch (error) { console.error(error); res.status(500).json({ error: 'Error adding document' }); } } -
다음과 같이 샘플 데이터를 이용하여 API를 테스트합니다:
fetch('/api/addDocument', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: '제품 이름', description: '제품 설명', price: 30000, }), });
검색 기능 구현하기
이제 OpenSearch를 활용하여 검색을 수행할 수 있는 기능을 설정합니다.
-
pages/api/search.js파일에 검색을 위한 API 라우트를 정의합니다:import { opensearchClient } from '../../lib/opensearchClient'; export default async function handler(req, res) { const { query } = req.query; try { const { body } = await opensearchClient.search({ index: 'products', body: { query: { multi_match: { query, fields: ['name', 'description'], }, }, }, }); const results = body.hits.hits.map(hit => hit._source); res.status(200).json({ results }); } catch (error) { console.error(error); res.status(500).json({ error: 'Error executing search' }); } }
UI에 검색 기능 통합하기
이제 Next.js 애플리케이션의 UI에 직접적으로 검색 기능을 통합해보겠습니다. components/Search.js 파일을 생성합니다:
import { useState } from 'react';
export default function Search() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const handleSearch = async () => {
const res = await fetch(`/api/search?query=${query}`);
const data = await res.json();
setResults(data.results);
};
return (
<div>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="제품 검색..."
/>
<button onClick={handleSearch}>검색</button>
<ul>
{results.map((result, index) => (
<li key={index}>
<h3>{result.name}</h3>
<p>{result.description}</p>
<p>{result.price}원</p>
</li>
))}
</ul>
</div>
);
}
pages/index.js에 Search 컴포넌트를 추가하여 애플리케이션에 검색 기능을 테스트해봅니다.
OpenSearch 성능 최적화
OpenSearch의 성능을 최적화하기 위한 몇 가지 전략을 알아봅니다:
- 인덱싱 전략 최적화: 사용 용도에 따라 데이터를 다양한 인덱스로 분리합니다.
- 쿼리 최적화: 캐시 친화적인 쿼리를 위해 매칭 대신 필터를 사용합니다.
- 노드 확장: 트래픽에 따라 OpenSearch 클러스터를 확장하거나 축소합니다.
참고자료 및 추가 리소스
위 링크들을 참고하여 더욱 깊이 있는 학습을 해보시길 바랍니다. 이 가이드를 통해 성공적으로 AWS OpenSearch를 Next.js 프로젝트에 통합해 보시기 바랍니다.