728x90

1. PostgreSQL의 알림 시스템 설정

PostgreSQL에서는 LISTENNOTIFY 명령어를 사용하여 데이터베이스의 변경 사항을 애플리케이션에 실시간으로 전달할 수 있습니다. 먼저 PostgreSQL에서 알림을 보낼 수 있도록 트리거를 설정합니다.

    -- 데이터 변경 후 알림을 보내는 함수 생성
    CREATE OR REPLACE FUNCTION notify_cache_update() RETURNS trigger AS $$
    BEGIN
      -- pg_notify를 사용해 알림을 보냄
      PERFORM pg_notify('cache_update_channel', NEW.id::TEXT);
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;

    -- 트리거 생성: 데이터베이스 업데이트 시 알림을 보냄
    CREATE TRIGGER trigger_cache_update
    AFTER INSERT OR UPDATE ON your_table
    FOR EACH ROW EXECUTE FUNCTION notify_cache_update();
  

위의 SQL 코드는 your_table에 데이터가 삽입되거나 수정될 때마다 pg_notify를 사용하여 'cache_update_channel' 채널로 알림을 보냅니다.

2. Node.js에서 PostgreSQL 알림 받기

Node.js 서버에서 pg 라이브러리를 사용하여 PostgreSQL의 알림을 수신하고 처리할 수 있습니다. 아래 코드는 PostgreSQL에서 알림을 수신하는 예시입니다.

    const { Client } = require('pg');

    // PostgreSQL 연결 설정
    const client = new Client({
      user: 'your_user',
      host: 'localhost',
      database: 'your_db',
      password: 'your_password',
      port: 5432,
    });

    client.connect();

    // 알림 채널을 리스닝
    client.query('LISTEN cache_update_channel');

    // 알림 받기
    client.on('notification', (msg) => {
      console.log('Received notification:', msg);
      // 알림을 받으면 캐시 갱신 등의 처리를 할 수 있습니다.
    });

    // 에러 처리
    client.on('error', (err) => {
      console.error('Error in PostgreSQL client:', err);
    });
  

이 코드에서 LISTEN 명령어로 'cache_update_channel' 채널에서 발생한 알림을 기다리고, notification 이벤트가 발생하면 알림을 처리합니다.

3. WebSocket 서버 구현

알림을 실시간으로 클라이언트에 전달하기 위해 Node.js에서 WebSocket 서버를 설정합니다. WebSocket은 클라이언트와 서버 간의 실시간 통신을 가능하게 해줍니다.

    const WebSocket = require('ws');

    // WebSocket 서버 설정
    const wss = new WebSocket.Server({ port: 8080 });

    wss.on('connection', (ws) => {
      console.log('A client connected');
      
      // PostgreSQL에서 알림을 받을 준비
      client.query('LISTEN cache_update_channel');
      
      client.on('notification', (msg) => {
        console.log('Received notification:', msg);
        ws.send(msg.payload);  // WebSocket 클라이언트로 알림 전송
      });
    });

    console.log('WebSocket server is running on ws://localhost:8080');
  

위 코드에서 WebSocket 서버를 설정하고, 클라이언트가 연결되면 PostgreSQL 알림을 받아 해당 알림을 클라이언트에 실시간으로 전달합니다.

4. SvelteKit에서 WebSocket 연결

SvelteKit에서는 클라이언트에서 WebSocket을 통해 실시간으로 서버와 통신할 수 있습니다. 아래 코드는 SvelteKit 클라이언트에서 WebSocket을 연결하고 알림을 수신하는 예시입니다.


      import { onMount } from 'svelte';

      let data: string;

      onMount(() => {
        const ws = new WebSocket('ws://localhost:8080'); // WebSocket 서버 연결

        ws.onopen = () => {
          console.log('WebSocket connected');
        };

        ws.onmessage = (event) => {
          console.log('Received message:', event.data);
          data = event.data; // 알림 데이터를 UI에 반영
        };

        ws.onerror = (error) => {
          console.error('WebSocket error:', error);
        };
      });
     <main>
       <h1>Real-time Notifications</h1>
       <p>{data}</p> <!-- 실시간 알림 데이터 표시 -->
     </main>

위 SvelteKit 코드는 WebSocket 서버에 연결하고, 알림을 받을 때마다 페이지에 표시합니다.

결론

PostgreSQL의 pg_notify를 사용하여 데이터베이스에서 실시간으로 알림을 보내고, 이를 Node.js 서버에서 WebSocket을 통해 SvelteKit 클라이언트에 전달하는 방법을 살펴보았습니다. 이 방식은 데이터베이스의 변경 사항을 실시간으로 클라이언트에게 반영할 수 있어, 사용자 경험을 향상시키는 데 유용합니다.

728x90
728x90

 

Elasticsearch는 대규모 데이터에서 빠르게 검색을 할 수 있도록 도와주는 검색 엔진입니다. 하지만 Elasticsearch 외에도 여러 다른 검색 솔루션이 존재하며, 각각 장점과 용도에 맞게 선택할 수 있습니다. 이번 포스팅에서는 Elasticsearch와 유사한 주요 검색 엔진들에 대해 알아보겠습니다.

1. Apache Solr

Apache Solr는 Elasticsearch와 비슷한 오픈소스 검색 플랫폼으로, Apache Lucene을 기반으로 합니다. Solr는 강력한 쿼리 기능, 분석 기능, 그리고 대규모 데이터셋에서 뛰어난 성능을 제공합니다.

  • 장점: 복잡한 쿼리와 집계 기능 지원, 커스터마이징 가능, Enterprise급 확장성.
  • 용도: 대규모의 검색 시스템, e-commerce 플랫폼 등에서 사용.

2. Amazon OpenSearch

Amazon OpenSearch는 Elasticsearch의 포크로, AWS에서 관리하는 오픈소스 검색 엔진입니다. Elasticsearch와 비슷하게 동작하지만, AWS와의 통합에 최적화되어 있습니다.

  • 장점: AWS와의 통합, 관리형 서비스 제공, OpenSearch Dashboards로 데이터 시각화.
  • 용도: AWS 환경에서 사용할 때 유리.

3. MeiliSearch

MeiliSearch는 빠르고 사용이 간편한 오픈소스 검색 엔진입니다. 상대적으로 작은 규모의 프로젝트에 적합합니다.

  • 장점: 빠른 검색 속도, 간단한 설정, 사용자 친화적인 API.
  • 용도: 중소형 프로젝트, 웹사이트 검색 등.

4. Algolia

Algolia는 클라우드 기반의 검색 서비스로, 실시간 검색 성능과 사용자 경험을 중시합니다. 검색 속도가 매우 빠르고, 설정이 간편합니다.

  • 장점: 실시간 검색, 자동 완성, 클라우드 기반 서비스.
  • 용도: 전자상거래 사이트, 모바일 앱, 웹 애플리케이션 등에서 사용.

5. Typesense

Typesense는 빠르고 안전한 검색을 제공하는 오픈소스 검색 엔진으로, 설정이 간단하고 검색 속도가 빠릅니다.

  • 장점: 빠른 검색 성능, 낮은 지연 시간, 쉬운 설치.
  • 용도: 웹 서비스, 모바일 앱 등에서 사용.

6. Azure Cognitive Search

Azure Cognitive Search는 Microsoft Azure에서 제공하는 검색 서비스로, AI 기반의 텍스트 분석과 검색 기능을 제공합니다.

  • 장점: Azure 클라우드 서비스와 통합, AI 기능 지원, 자동 확장 가능.
  • 용도: 대규모 기업용 검색 시스템, Azure 환경에서 사용 시 강력한 선택.

7. Xapian

Xapian은 오픈소스 검색 라이브러리로, 텍스트 검색을 위한 유연한 솔루션을 제공합니다. C++로 구현되어 있어 빠른 성능을 자랑합니다.

  • 장점: 다양한 언어 지원, 유연한 검색 방법, 빠른 성능.
  • 용도: 작은 규모의 검색 시스템, 다양한 언어로 사용할 수 있음.

8. RedisSearch

RedisSearch는 Redis의 모듈로, 인메모리 기반의 빠른 검색 기능을 제공합니다. 실시간 검색과 자동 완성, 필터링 기능을 제공합니다.

  • 장점: 인메모리 기반으로 빠른 속도, 실시간 검색, 확장 가능.
  • 용도: 실시간 검색 시스템, 추천 시스템 등.

결론

Elasticsearch 외에도 다양한 검색 엔진들이 존재하며, 각 검색 엔진은 특성에 맞는 용도와 장점이 있습니다. 선택은 프로젝트의 요구 사항과 사용 환경에 따라 달라질 수 있습니다:

  • 대규모 검색 시스템: Elasticsearch, Apache Solr, Amazon OpenSearch.
  • 클라우드 기반 관리형 서비스: Algolia, Azure Cognitive Search.
  • 빠르고 간단한 사용: MeiliSearch, Typesense.
  • Redis 기반 검색: RedisSearch.

이 각 검색 엔진은 설정 용이성, 성능, 기능성에서 차이를 보이므로, 사용하려는 데이터의 크기나 검색 요구 사항을 고려하여 적합한 솔루션을 선택하는 것이 중요합니다.

728x90

'DB' 카테고리의 다른 글

Nosql을 위한 Elasticsearch로 정보 통합 검색하기  (0) 2025.02.22
728x90

 

Elasticsearch는 대규모 데이터에서 빠른 검색을 가능하게 해주는 분산 검색 엔진입니다. 이번 포스팅에서는 두 개의 데이터베이스(영화 DB와 배우 DB)를 Elasticsearch에 인덱싱하여, 영화와 배우 정보를 통합적으로 검색하는 방법에 대해 설명하겠습니다.

1. 영화 DB와 배우 DB 구조

가장 먼저, 영화와 배우 정보를 담고 있는 두 개의 데이터베이스가 있습니다.

DB1: 영화 정보

    | 영화 ID | 제목           | 장르 | 개봉일     | 출연 배우 목록 (배우 ID들) |
    |---------|----------------|------|------------|------------------------|
    | 1       | "Inception"    | 액션 | 2010-07-16 | [101, 102]              |
    | 2       | "Titanic"      | 드라마 | 1997-12-19 | [102, 103]              |
    

DB2: 배우 정보

    | 배우 ID | 배우 이름        | 생년월일   | 출연 영화 목록 (영화 ID들) |
    |---------|------------------|------------|------------------------|
    | 101     | Leonardo DiCaprio | 1974-11-11 | [1, 2]                  |
    | 102     | Kate Winslet     | 1975-10-05 | [1, 2]                  |
    | 103     | Billy Zane       | 1966-02-24 | [2]                     |
    

2. Elasticsearch에 데이터 인덱싱

이제 이 두 데이터를 Elasticsearch에 인덱싱하여, 빠르게 검색할 수 있도록 준비하겠습니다.

영화 데이터 인덱싱

    await client.index({
      index: 'movies',  // Elasticsearch 인덱스 이름
      id: '1',          // 영화 ID
      body: {
        title: 'Inception',
        genre: 'Action',
        release_date: '2010-07-16',
        actor_ids: [101, 102],  // 출연 배우 ID 목록
      }
    });
    

배우 데이터 인덱싱

    await client.index({
      index: 'actors',  // Elasticsearch 인덱스 이름
      id: '101',        // 배우 ID
      body: {
        name: 'Leonardo DiCaprio',
        birth_date: '1974-11-11',
        movie_ids: [1, 2],  // 출연 영화 ID 목록
      }
    });
    

3. Elasticsearch에서 통합 검색

이제 Elasticsearch에서 영화와 배우 데이터를 통합하여 검색할 수 있습니다. 예를 들어, 배우 이름으로 영화 정보를 검색하거나, 영화 제목으로 출연 배우를 찾을 수 있습니다.

배우 이름으로 영화 검색

    async function searchMoviesByActor(actorName) {
      const { body } = await client.search({
        index: 'actors',
        body: {
          query: {
            match: {
              name: actorName  // 배우 이름으로 검색
            }
          }
        }
      });

      const actor = body.hits.hits[0]?._source;  // 첫 번째 검색 결과에서 배우 정보 추출
      const movieIds = actor?.movie_ids;         // 해당 배우가 출연한 영화 ID 목록

      // 영화 ID로 영화 정보 검색
      const movieSearchResults = await client.mget({
        index: 'movies',
        body: {
          ids: movieIds.map(id => id.toString())  // 영화 ID를 사용하여 영화 정보 검색
        }
      });

      console.log(movieSearchResults.body.docs);
    }

    // 예시: Leonardo DiCaprio가 출연한 영화 검색
    searchMoviesByActor('Leonardo DiCaprio');
    

4. Elasticsearch에서 데이터 통합 검색의 장점

Elasticsearch를 사용하여 영화와 배우 정보를 통합 검색하면, 여러 가지 장점이 있습니다:

  • 빠른 검색: Elasticsearch는 분산 검색에 최적화되어 있어, 대규모 데이터에서 빠르게 검색 결과를 제공합니다.
  • 복합 검색 가능: 영화 제목, 배우 이름, 장르 등 여러 필드를 기준으로 동시에 검색할 수 있습니다.
  • 유연한 검색: 배우 이름으로 영화 정보를 검색하거나, 영화 제목으로 배우 정보를 검색하는 등 다양한 방식의 검색이 가능합니다.

결론

Elasticsearch는 영화와 배우 데이터를 **하나의 인덱스**에서 통합하여 빠르고 유연하게 검색할 수 있도록 해줍니다. 두 데이터베이스(영화 DB와 배우 DB)를 Elasticsearch에 인덱싱하면, 서로 다른 데이터베이스에 저장된 정보를 통합적으로 검색할 수 있는 강력한 검색 시스템을 구축할 수 있습니다.

728x90

'DB' 카테고리의 다른 글

Elasticsearch 외의 검색 엔진들  (0) 2025.02.22
728x90

1. KEYS 명령어 사용

Redis에서 특정 패턴에 맞는 키를 조회하려면 KEYS 명령어를 사용할 수 있습니다. 예를 들어, data:*와 같은 패턴을 사용하여 data:0, data:1와 같은 키를 가져올 수 있습니다.

# Python 예시: KEYS 명령어 사용
import redis

# Redis 연결
r = redis.StrictRedis(host='localhost', port=6379, db=0)

# "data:"로 시작하는 모든 키를 조회
keys = r.keys('data:*')
print(keys)  # ['data:0', 'data:1', ...]
        

주의: KEYS 명령어는 Redis 서버에서 모든 키를 순회하기 때문에, 키가 많을 경우 성능에 영향을 미칠 수 있습니다.

2. SCAN 명령어 사용

SCAN 명령어는 KEYS보다 성능에 더 유리한 방법입니다. SCAN은 비차단적이며, 키를 순차적으로 조회할 수 있어 대규모 데이터셋에서 성능 저하를 줄일 수 있습니다.

# Python 예시: SCAN 명령어 사용
import redis

# Redis 연결
r = redis.StrictRedis(host='localhost', port=6379, db=0)

# SCAN을 사용하여 'data:'로 시작하는 키 조회
cursor = 0
while True:
    cursor, keys = r.scan(cursor=cursor, match='data:*', count=10)
    print(keys)  # data:0, data:1, ...
    if cursor == 0:
        break
        

SCAN은 키를 순차적으로 조회하므로 성능에 더 유리합니다. 특히, 많은 키가 있는 환경에서 유용하게 사용할 수 있습니다.

3. 직접 키 접근 (직접 data:0, data:1 조회)

키가 일정한 규칙을 따른다면, 직접 키를 지정하여 값을 가져올 수 있습니다. 예를 들어, data:0, data:1와 같은 키가 있을 경우 해당 키를 직접 조회할 수 있습니다.

# Python 예시: 직접 키 접근
import redis

# Redis 연결
r = redis.StrictRedis(host='localhost', port=6379, db=0)

# 직접 키를 지정하여 값 조회
data_0 = r.get('data:0')
data_1 = r.get('data:1')

print(data_0)  # data:0에 저장된 값
print(data_1)  # data:1에 저장된 값
        

이 방법은 특정 키만 조회하므로, 성능 면에서는 가장 효율적입니다.

4. 파이프라인을 사용한 여러 키 조회

여러 개의 키를 동시에 조회해야 할 경우, Redis의 파이프라인 기능을 사용할 수 있습니다. 파이프라인을 사용하면 여러 명령어를 하나의 요청으로 묶어서 실행할 수 있어 성능을 최적화할 수 있습니다.

# Python 예시: 파이프라인을 사용한 여러 키 조회
import redis

# Redis 연결
r = redis.StrictRedis(host='localhost', port=6379, db=0)

# 파이프라인 사용하여 여러 키 조회
pipeline = r.pipeline()
pipeline.get('data:0')
pipeline.get('data:1')

results = pipeline.execute()
print(results)  # [data:0의 값, data:1의 값]
        

파이프라인을 사용하면 여러 Redis 명령어를 한번에 처리할 수 있기 때문에 성능이 향상됩니다.

Redis에서 키를 효율적으로 조회하는 방법을 알아보았습니다. 상황에 맞는 방법을 선택하여 사용하세요.

728x90
728x90

 

이 포스트에서는 MongoDB에 데이터를 삽입하기 전에 중복 데이터가 있는지 확인하고, 중복이 없으면 데이터를 삽입하는 방법에 대해 설명합니다.

1. MongoDB 연결

먼저, MongoDB에 연결하기 위해 pymongo 라이브러리를 설치해야 합니다. 아래 명령어를 사용하여 설치할 수 있습니다:

pip install pymongo

MongoDB에 연결하기 위해서는 MongoClient를 사용하여 연결합니다:


from pymongo import MongoClient

# MongoDB 연결
client = MongoClient('mongodb://localhost:27017')  # MongoDB 서버 주소
db = client['myDatabase']  # 사용할 데이터베이스
collection = db['myCollection']  # 사용할 컬렉션
        

2. 중복 데이터 확인 후 삽입

데이터를 삽입하기 전에 중복 데이터를 확인하려면 find_one 메서드를 사용하여 특정 조건을 만족하는 데이터가 있는지 확인합니다. 예를 들어, 'name' 필드를 기준으로 중복 여부를 확인할 수 있습니다.

다음 코드는 중복을 확인하고, 중복이 없으면 데이터를 삽입하는 예제입니다:


def insert_data_if_not_exists(data):
    # 중복 데이터를 확인할 조건을 설정 (예: 'name' 필드가 중복되는지 확인)
    existing_data = collection.find_one({'name': data['name']})

    if existing_data:
        print(f"중복 데이터가 존재합니다: {data['name']}")
    else:
        collection.insert_one(data)
        print(f"데이터가 성공적으로 삽입되었습니다: {data['name']}")

# 예시 데이터
data_to_insert = {'name': 'John Doe', 'age': 30, 'city': 'New York'}

# 데이터 삽입 시도
insert_data_if_not_exists(data_to_insert)
        

3. 코드 설명

  • MongoClient: MongoDB 서버에 연결합니다. 위 코드에서는 로컬 서버 (localhost:27017)에 연결합니다.
  • find_one: 특정 조건에 맞는 데이터가 존재하는지 확인합니다. 예제에서는 'name' 필드를 기준으로 중복 여부를 체크합니다.
  • insert_one: 중복 데이터가 없다면 새로운 데이터를 삽입합니다.
  • 중복 확인: 중복이 발견되면 삽입하지 않고 메시지를 출력합니다.

4. 중복 확인 조건 변경하기

위 예제에서는 'name' 필드만을 기준으로 중복을 확인했지만, 여러 조건을 조합하여 중복 확인을 할 수도 있습니다. 예를 들어, 'name''city' 필드를 동시에 확인하려면 아래와 같이 조건을 설정할 수 있습니다:


existing_data = collection.find_one({'name': data['name'], 'city': data['city']})
        

이 포스트가 MongoDB와 Python을 활용한 데이터 삽입에 도움이 되었기를 바랍니다!

728x90
728x90

MongoDB에서 SQL처럼 여러 필드를 한 번에 가져오고 조건을 설정하는 방법을 알아보겠습니다. MongoDB는 관계형 데이터베이스와는 다른 구조이므로, SQL처럼 데이터를 가져오는 방식이 다릅니다. 하지만 몇 가지 방법을 사용하면 SQL처럼 원하는 필드를 선택하고, 조건을 설정해 데이터를 효율적으로 조회할 수 있습니다.

1. Aggregation Pipeline 사용하기

MongoDB의 Aggregation Pipeline을 사용하면 복잡한 데이터 변형과 필터링을 수행할 수 있습니다. SQL에서 SELECT와 유사하게 필드를 지정하고, 여러 필드를 한번에 처리할 수 있습니다.


from pymongo import MongoClient

# MongoDB 클라이언트 연결
client = MongoClient('mongodb://localhost:27017/')  # MongoDB 서버 주소 (로컬 환경일 경우)
db = client['your_database_name']  # 데이터베이스 선택
collection = db['your_collection_name']  # 컬렉션 선택

# Aggregation Pipeline을 사용하여 여러 필드 추출
pipeline = [
    {
        "$project": {  # 필드 선택
            "field_name": 1,
            "other_field": 1,  # 다른 필드도 추가 가능
            "_id": 0  # _id 제외
        }
    },
    {
        "$limit": 1000  # 최대 1,000개만 가져오기
    }
]

documents = collection.aggregate(pipeline)

# 출력 (예시)
for document in documents:
    print(document)

설명: $project는 선택하려는 필드를 지정하는 부분으로, SQL의 SELECT와 유사합니다. $limit을 사용해 최대 개수를 설정할 수 있습니다.

2. find() 메서드로 여러 필드 지정하기

find() 메서드를 사용하여 SQL처럼 여러 필드를 지정할 수도 있습니다. projection을 통해 반환할 필드를 설정할 수 있습니다.


documents = collection.find(
    {},  # 모든 문서 가져오기
    {"field_name": 1, "other_field": 1, "_id": 0}  # 필요한 필드만 가져오기
).limit(1000)

이 방법을 사용하면 필요한 필드만 가져올 수 있습니다.

3. 복잡한 조건을 가진 find() 쿼리

SQL에서의 WHERE 조건과 유사하게, MongoDB에서는 find() 메서드에 조건을 추가하여 데이터를 필터링할 수 있습니다.


documents = collection.find(
    {"field_name": {"$regex": "example", "$options": "i"}},  # 조건을 추가
    {"field_name": 1, "other_field": 1, "_id": 0}  # 반환할 필드 지정
).limit(1000)

위 예제는 field_name에 "example"이 포함된 데이터를 찾는 조건을 설정한 것입니다.

4. 배치로 데이터 가져오기

SQL처럼 데이터를 한 번에 여러 건 가져오고 싶은 경우, batch_size를 설정하여 한 번에 데이터를 가져올 수 있습니다.


documents = collection.find(
    {},  # 모든 문서 가져오기
    {"field_name": 1, "_id": 0}  # 필요한 필드만 가져오기
).batch_size(1000)  # 한 번에 가져올 배치 크기 설정

# 출력 (예시)
for document in documents:
    print(document)

이 방법을 사용하면 한 번에 많은 데이터를 가져올 수 있습니다.

5. SQL-like 방식 (MongoDB의 JOIN 기능)

MongoDB는 SQL처럼 JOIN을 직접적으로 지원하지 않지만, $lookup을 사용하면 관계형 데이터베이스의 JOIN처럼 다른 컬렉션과 결합하여 데이터를 가져올 수 있습니다. 그러나 MongoDB는 관계형 데이터베이스처럼 설계된 데이터가 아니므로, JOIN 대신 lookup을 활용한 방식이 더 효율적일 수 있습니다.

MongoDB에서 SQL처럼 여러 필드를 지정하고 데이터를 가져오는 방법을 정리하였습니다. Aggregation Pipeline이나 find() 메서드를 적절히 사용하여 효율적으로 데이터를 조회할 수 있습니다.

728x90

+ Recent posts