Skip to main content
Core.Today

Databases

OpenSearch 기반의 고성능 문서 데이터베이스입니다. 스키마 정의, CRUD, 전문 검색, 벡터 검색을 지원합니다.

주요 기능

  • 스키마 정의: 필드 타입, 인덱싱 옵션, 벡터 필드 설정
  • CRUD 작업: 단일/대량 문서 생성, 조회, 수정, 삭제
  • 전문 검색: OpenSearch Query DSL 지원 (match, term, bool, range)
  • 벡터 검색: k-NN 기반 시맨틱 검색 (Pro 플랜 이상)
  • 집계: terms, date_histogram, 통계 집계

크레딧 비용

데이터베이스 작업은 유형에 따라 크레딧이 차감됩니다. 작업 실패 시 크레딧은 자동 환불됩니다.

작업엔드포인트크레딧
문서 생성POST /documents0.1
문서 조회GET /documents/{id}0.05
문서 수정PUT, PATCH /documents/{id}0.1
문서 삭제DELETE /documents/{id}0.05
대량 생성POST /documents/_bulk5.0 / 100건
대량 삭제POST /documents/_bulk_delete0.05 / 건
대량 수정POST /documents/_bulk_update0.1 / 건
전문 검색POST /search0.5
집계POST /aggregate1.0
벡터 검색POST /search/vector2.0

무료: 데이터베이스 생성/삭제, 목록 조회, 스키마 변경, 통계 조회, 문서 목록 조회, 문서 수 조회(_count)는 크레딧이 차감되지 않습니다.

플랜별 제한

구독 플랜에 따라 데이터베이스 리소스 제한이 다릅니다.

항목FreeProTeamEnterprise
최대 데이터베이스 수15201,000
DB당 최대 문서 수10,000500,0005,000,000100,000,000
최대 스토리지100 MB5 GB50 GB500 GB
최대 문서 크기100 KB1 MB10 MB100 MB
벌크 작업 최대 건수1001,00010,000100,000
벡터 검색-1,536차원2,048차원4,096차원
1

데이터베이스 생성

스키마와 함께 새 데이터베이스를 생성합니다. 데이터베이스 이름은 팀 내에서 고유해야 합니다.

이름 규칙

  • 소문자 영문으로 시작해야 합니다
  • 소문자 영문, 숫자, 하이픈(-), 언더스코어(_)만 사용 가능
  • 3~50자 이내
  • aiapi_, db_system_, _로 시작할 수 없음 (예약 접두사)
curl -X POST https://api.core.today/v1/databases \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "products",
    "display_name": "Product Catalog",
    "description": "E-commerce product database",
    "schema_fields": {
      "title": {"type": "text", "index": true},
      "description": {"type": "text", "index": true},
      "price": {"type": "float"},
      "category": {"type": "keyword"},
      "tags": {"type": "keyword"},
      "in_stock": {"type": "boolean"},
      "created_at": {"type": "date"}
    }
  }'

응답 예시

{
  "database_uid": "db_abc123",
  "name": "products",
  "display_name": "Product Catalog",
  "description": "E-commerce product database",
  "team_id": "team_xyz",
  "schema_fields": {...},
  "document_count": 0,
  "created_at": "2024-12-26T10:00:00Z"
}

지원 필드 타입

타입설명예시
text전문 검색이 가능한 텍스트"Product description..."
keyword정확한 매칭용 문자열 (필터, 집계)"electronics"
integer정수42
long64비트 정수9223372036854775807
float32비트 부동 소수점19.99
double64비트 부동 소수점3.141592653589793
booleantrue/falsetrue
dateISO 8601 날짜"2024-12-26T10:00:00Z"
object중첩 객체 (인덱싱 on/off 가능){"key": "value"}
nested독립적으로 쿼리 가능한 객체 배열[{"name": "A"}, ...]
knn_vector벡터 검색용 임베딩 (Pro+)[0.1, 0.2, ...]

벡터 필드 설정

벡터 검색을 위한 필드는 dimension과 space_type을 지정해야 합니다:

"embedding": {
  "type": "knn_vector",
  "dimension": 1536,
  "space_type": "cosinesimil"
}
2

문서 CRUD

자동 메타데이터 (_meta)

모든 문서에는 _meta 필드가 자동으로 추가됩니다:

  • _meta.created_at — 문서 생성 시각 (ISO 8601)
  • _meta.updated_at — 마지막 수정 시각 (ISO 8601)
  • _meta.created_by_api_key — 생성에 사용된 API 키 UID

문서 생성

# 단일 문서 생성
curl -X POST https://api.core.today/v1/databases/{database_uid}/documents \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "product-001",
    "data": {
      "title": "Wireless Headphones",
      "description": "High-quality wireless headphones with noise cancellation",
      "price": 199.99,
      "category": "electronics",
      "tags": ["audio", "wireless", "premium"],
      "in_stock": true
    }
  }'

대량 문서 생성

curl -X POST https://api.core.today/v1/databases/{database_uid}/documents/_bulk \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "documents": [
      {"id": "product-001", "data": {"title": "Product 1", "price": 99.99}},
      {"id": "product-002", "data": {"title": "Product 2", "price": 149.99}},
      {"id": "product-003", "data": {"title": "Product 3", "price": 199.99}}
    ]
  }'

응답: 성공/실패 개수와 에러 상세 정보가 반환됩니다.

문서 조회

# 특정 문서 조회
curl https://api.core.today/v1/databases/{database_uid}/documents/{doc_id} \
  -H "X-API-Key: cdt_your_api_key"

# 특정 필드만 조회 (Field Projection)
curl "https://api.core.today/v1/databases/{database_uid}/documents/{doc_id}?_source=title,price" \
  -H "X-API-Key: cdt_your_api_key"

# 문서 목록 조회 (페이지네이션)
curl "https://api.core.today/v1/databases/{database_uid}/documents?size=20&from=0" \
  -H "X-API-Key: cdt_your_api_key"

# 문서 목록 - 특정 필드만 조회
curl "https://api.core.today/v1/databases/{database_uid}/documents?size=20&_source=title,price" \
  -H "X-API-Key: cdt_your_api_key"

_source: 쉼표로 구분된 필드 목록을 지정하면 해당 필드만 응답에 포함됩니다. 생략하면 모든 필드를 반환합니다.

문서 수정

# 전체 교체 (PUT)
curl -X PUT https://api.core.today/v1/databases/{database_uid}/documents/{doc_id} \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"data": {"title": "Updated Title", "price": 299.99, ...}}'

# 부분 수정 (PATCH)
curl -X PATCH https://api.core.today/v1/databases/{database_uid}/documents/{doc_id} \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"data": {"price": 179.99}}'

문서 삭제

curl -X DELETE https://api.core.today/v1/databases/{database_uid}/documents/{doc_id} \
  -H "X-API-Key: cdt_your_api_key"

대량 삭제

curl -X POST https://api.core.today/v1/databases/{database_uid}/documents/_bulk_delete \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "ids": ["product-001", "product-002", "product-003"]
  }'

크레딧: 0.05 × 문서 수. 존재하지 않는 ID는 에러로 보고됩니다.

대량 수정

curl -X POST https://api.core.today/v1/databases/{database_uid}/documents/_bulk_update \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "documents": [
      {"id": "product-001", "data": {"price": 179.99, "in_stock": false}},
      {"id": "product-002", "data": {"price": 129.99}},
      {"id": "product-003", "data": {"category": "accessories"}}
    ]
  }'

크레딧: 0.1 × 문서 수. 부분 수정(PATCH)으로 동작하며 지정된 필드만 업데이트됩니다.

문서 수 조회

# 전체 문서 수
curl https://api.core.today/v1/databases/{database_uid}/documents/_count \
  -H "X-API-Key: cdt_your_api_key"

# 조건부 문서 수 (query 파라미터로 JSON 전달)
curl "https://api.core.today/v1/databases/{database_uid}/documents/_count?q=%7B%22term%22%3A%7B%22category%22%3A%22electronics%22%7D%7D" \
  -H "X-API-Key: cdt_your_api_key"

무료: 크레딧이 차감되지 않습니다. 응답: {"count": 1234}

필드 제외 (_source_excludes)

응답에서 특정 필드를 제외할 수 있습니다. _source와 함께 사용하면 includes/excludes로 변환됩니다.

# GET 요청 - 쿼리 파라미터로 사용
curl "https://api.core.today/v1/databases/{database_uid}/documents?_source_excludes=embedding,raw_html" \
  -H "X-API-Key: cdt_your_api_key"

# POST (search) - body에 포함
curl -X POST https://api.core.today/v1/databases/{database_uid}/search \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "query": {"match_all": {}},
    "_source": ["title", "price"],
    "_source_excludes": ["embedding"]
  }'
3

검색

OpenSearch Query DSL을 사용한 강력한 검색 기능을 제공합니다.

전문 검색 (Full-text)

curl -X POST https://api.core.today/v1/databases/{database_uid}/search \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "query": {
      "match": {
        "description": "wireless headphones"
      }
    },
    "size": 10,
    "from": 0,
    "_source": ["title", "price", "category"]
  }'

_source: 응답에 포함할 필드 목록입니다. 생략하면 모든 필드를 반환합니다.

복합 검색 (Boolean Query)

{
  "query": {
    "bool": {
      "must": [
        {"match": {"description": "headphones"}}
      ],
      "filter": [
        {"term": {"category": "electronics"}},
        {"range": {"price": {"gte": 100, "lte": 300}}}
      ],
      "should": [
        {"term": {"in_stock": true}}
      ]
    }
  },
  "sort": [
    {"price": {"order": "asc"}}
  ],
  "highlight": {
    "fields": {"description": {}}
  }
}

Deep Pagination (search_after)

from + size가 10,000을 초과하면 search_after를 사용해야 합니다. 이전 결과의 마지막 sort 값을 전달하여 다음 페이지를 조회합니다.

{
  "query": {"match_all": {}},
  "sort": [
    {"_meta.created_at": {"order": "desc"}},
    {"_id": {"order": "asc"}}
  ],
  "size": 100,
  "search_after": ["2025-01-01T00:00:00Z", "product-500"]
}

주의: search_after 사용 시 반드시 sort를 지정해야 하며, tie-breaker로 _id를 포함하는 것을 권장합니다.

검색 응답 예시

{
  "total": 42,
  "hits": [
    {
      "id": "product-001",
      "score": 1.5,
      "data": {
        "title": "Wireless Headphones",
        "price": 199.99,
        ...
      },
      "highlight": {
        "description": ["High-quality <em>wireless</em> <em>headphones</em>..."]
      }
    }
  ]
}
4

벡터 검색 (k-NN)

Pro+

임베딩 벡터를 사용한 시맨틱 유사도 검색입니다. AI 모델로 생성한 텍스트/이미지 임베딩을 저장하고 검색할 수 있습니다.

벡터 필드가 있는 스키마

{
  "name": "articles",
  "schema_fields": {
    "title": {"type": "text"},
    "content": {"type": "text"},
    "embedding": {
      "type": "knn_vector",
      "dimension": 1536,
      "space_type": "cosinesimil"
    }
  }
}

벡터 검색 요청

curl -X POST https://api.core.today/v1/databases/{database_uid}/search/vector \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "field": "embedding",
    "vector": [0.1, 0.2, 0.3, ...],
    "k": 10,
    "filter": {
      "term": {"category": "technology"}
    },
    "_source": ["title", "content"]
  }'

임베딩 생성 팁

OpenAI의 text-embedding-3-small (1536차원) 또는 Cohere의 임베딩 모델을 사용하여 텍스트를 벡터로 변환할 수 있습니다. LLM API를 통해 임베딩을 생성하고 데이터베이스에 저장하세요.

5

집계 (Aggregations)

데이터 분석을 위한 집계 기능을 제공합니다.

curl -X POST https://api.core.today/v1/databases/{database_uid}/aggregate \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "query": {"match_all": {}},
    "aggregations": {
      "by_category": {
        "terms": {"field": "category", "size": 10}
      },
      "avg_price": {
        "avg": {"field": "price"}
      },
      "price_ranges": {
        "range": {
          "field": "price",
          "ranges": [
            {"to": 100},
            {"from": 100, "to": 200},
            {"from": 200}
          ]
        }
      }
    }
  }'

집계 응답 예시

{
  "total": 1000,
  "aggregations": {
    "by_category": {
      "buckets": [
        {"key": "electronics", "doc_count": 350},
        {"key": "clothing", "doc_count": 280},
        ...
      ]
    },
    "avg_price": {"value": 149.99},
    "price_ranges": {
      "buckets": [
        {"key": "*-100.0", "doc_count": 200},
        {"key": "100.0-200.0", "doc_count": 500},
        {"key": "200.0-*", "doc_count": 300}
      ]
    }
  }
}
6

데이터베이스 관리

데이터베이스 목록

curl https://api.core.today/v1/databases \
  -H "X-API-Key: cdt_your_api_key"

필드 추가

기존 데이터베이스에 새 필드를 추가할 수 있습니다. 기존 필드의 타입은 변경할 수 없습니다.

curl -X POST https://api.core.today/v1/databases/{database_uid}/fields \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": {
      "rating": {"type": "float"},
      "reviews_count": {"type": "integer"}
    }
  }'

통계 조회

curl https://api.core.today/v1/databases/{database_uid}/stats \
  -H "X-API-Key: cdt_your_api_key"

데이터베이스 삭제

주의: 데이터베이스 삭제는 되돌릴 수 없습니다. 모든 문서가 영구 삭제됩니다.

curl -X DELETE https://api.core.today/v1/databases/{database_uid} \
  -H "X-API-Key: cdt_your_api_key"

필드값 자동완성 (Suggest)

keyword 타입 필드의 값을 자동완성으로 조회합니다.

curl "https://api.core.today/v1/databases/{database_uid}/suggest?field=category&prefix=ele&limit=10" \
  -H "X-API-Key: cdt_your_api_key"

# 응답: {"suggestions": ["electronics", "electric-vehicles", ...]}

무료: 크레딧이 차감되지 않습니다.

쿼리 저장

자주 사용하는 검색 쿼리를 저장하고 관리할 수 있습니다. 모두 무료입니다.

# 쿼리 저장
curl -X POST https://api.core.today/v1/databases/{database_uid}/queries \
  -H "X-API-Key: cdt_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "할인 상품 검색",
    "description": "100원 미만 전자제품",
    "query": {
      "bool": {
        "filter": [
          {"term": {"category": "electronics"}},
          {"range": {"price": {"lt": 100}}}
        ]
      }
    }
  }'

# 저장된 쿼리 목록
curl https://api.core.today/v1/databases/{database_uid}/queries \
  -H "X-API-Key: cdt_your_api_key"

# 저장된 쿼리 삭제
curl -X DELETE https://api.core.today/v1/databases/{database_uid}/queries/{query_uid} \
  -H "X-API-Key: cdt_your_api_key"

SDK 예제

JavaScript / TypeScript

import axios from 'axios';

const api = axios.create({
  baseURL: 'https://api.core.today/v1',
  headers: { 'X-API-Key': 'cdt_your_api_key' }
});

// 문서 생성
const doc = await api.post('/databases/db_abc123/documents', {
  id: 'product-001',
  data: { title: 'My Product', price: 99.99 }
});

// 검색
const results = await api.post('/databases/db_abc123/search', {
  query: { match: { title: 'product' } },
  size: 10
});

console.log(results.data.hits);

Python

import requests

API_KEY = "cdt_your_api_key"
BASE_URL = "https://api.core.today/v1"
headers = {"X-API-Key": API_KEY}

# 문서 생성
response = requests.post(
    f"{BASE_URL}/databases/db_abc123/documents",
    headers=headers,
    json={
        "id": "product-001",
        "data": {"title": "My Product", "price": 99.99}
    }
)

# 검색
results = requests.post(
    f"{BASE_URL}/databases/db_abc123/search",
    headers=headers,
    json={
        "query": {"match": {"title": "product"}},
        "size": 10
    }
)

for hit in results.json()["hits"]:
    print(hit["data"]["title"])

에러 응답

요청 실패 시 다음과 같은 에러 응답이 반환됩니다. 크레딧이 차감된 작업이 실패하면 자동으로 환불됩니다.

402 — 크레딧 부족

{
  "detail": "Insufficient credits. Required: 0.50, Available: 0.12"
}

404 — 데이터베이스 또는 문서 없음

{
  "detail": "Database not found"
}
// 또는
{
  "detail": "Document not found"
}

400 — 유효성 검증 실패

{
  "detail": "Database with name 'products' already exists"
}
// 또는
{
  "detail": "Invalid query: Query type 'script' is not allowed"
}
// 또는
{
  "detail": "Pagination limit exceeded: from (9990) + size (20) = 10010 exceeds maximum of 10000. Use search_after for deep pagination."
}

403 — 플랜 제한

{
  "detail": "Vector search is not available in your plan"
}
// 또는
{
  "detail": "Maximum number of databases (1) reached for your plan"
}

Best Practices

  • 스키마 설계: 검색에 자주 사용되는 필드는 keyword 타입으로, 전문 검색이 필요한 필드는 text 타입으로 지정하세요.
  • 대량 작업: 여러 문서를 처리할 때는 /_bulk 엔드포인트를 사용하세요.
  • 페이지네이션: from + size는 최대 10,000까지 가능합니다. 그 이상은 search_after sort를 함께 사용하세요.
  • 필터 vs 쿼리: 정확한 값 매칭은 filter에, 점수 계산이 필요한 검색은 query에 작성하세요.
  • 벡터 검색: 벡터 차원은 임베딩 모델에 맞게 설정하고, 필터와 함께 사용하면 더 효율적입니다.