MDDB Usage Examples

Basic Operations

Adding Documents

curl -X POST http://localhost:11023/v1/add \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "key": "hello",
    "lang": "en_US",
    "meta": {"category": ["blog"]},
    "contentMd": "# Hello World"
  }'

curl -X POST http://localhost:11023/v1/add \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "key": "tutorial",
    "lang": "en_US",
    "meta": {
      "category": ["tutorial", "beginner"],
      "tags": ["golang", "database", "markdown"],
      "author": ["John Doe"]
    },
    "contentMd": "# Tutorial Content"
  }'

Retrieving Documents

curl -X POST http://localhost:11023/v1/get \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "key": "hello",
    "lang": "en_US"
  }'

curl -X POST http://localhost:11023/v1/get \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "key": "hello",
    "lang": "en_US",
    "env": {
      "year": "2024",
      "siteName": "My Blog"
    }
  }'

Search Examples

Basic Search

curl -X POST http://localhost:11023/v1/search \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "limit": 50
  }'

curl -X POST http://localhost:11023/v1/search \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "filterMeta": {"category": ["tutorial"]},
    "sort": "addedAt",
    "asc": false
  }'

Advanced Filtering

curl -X POST http://localhost:11023/v1/search \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "filterMeta": {
      "category": ["tutorial", "guide", "howto"]
    }
  }'

curl -X POST http://localhost:11023/v1/search \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "filterMeta": {
      "category": ["tutorial"],
      "author": ["John Doe"],
      "status": ["published"]
    }
  }'

Pagination

curl -X POST http://localhost:11023/v1/search \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "limit": 10,
    "offset": 0
  }'

curl -X POST http://localhost:11023/v1/search \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "limit": 10,
    "offset": 10
  }'

Full-Text Search (v2.9.12+ and v2.9.13+ features)

curl -X POST http://localhost:11023/v1/fts \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "query": "tutorial",
    "algorithm": "bm25",
    "boost": {"tag:featured": 5.0, "status:archived": -2.0}
  }'

curl "http://localhost:11023/v1/autocomplete?collection=blog&q=mar&topN=5"

curl -X POST http://localhost:11023/v1/fts \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "query": "(rust OR golang) AND \"async runtime\"~3 NOT legacy",
    "mode": "expression"
  }'

curl -X POST http://localhost:11023/v1/fts \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "query": "markdown database",
    "highlight": true,
    "highlightTag": "<mark>",
    "maxHighlights": 2,
    "fragmentSize": 120
  }'

Hybrid Search with Geo Distance Sort (v2.9.13+)

curl -X POST http://localhost:11023/v1/hybrid-search \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "venues",
    "query": "coffee wifi",
    "topK": 10,
    "geo": {"lat": 52.52, "lng": 13.405, "radiusMeters": 3000},
    "sort": "distance"
  }'

GeoJSON Polygon / Multi-Polygon Containment (v2.9.13+)

curl -X POST http://localhost:11023/v1/geo-polygon \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "venues",
    "polygon": {
      "type": "Polygon",
      "coordinates": [
        [[13.36,52.51],[13.42,52.51],[13.42,52.53],[13.36,52.53],[13.36,52.51]]
      ]
    }
  }'

curl -X POST http://localhost:11023/v1/geo-polygon \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "venues",
    "polygon": {
      "coordinates": [
        [[0,0],[10,0],[10,10],[0,10],[0,0]],
        [[3,3],[7,3],[7,7],[3,7],[3,3]]
      ]
    }
  }'

curl -X POST http://localhost:11023/v1/geo-polygon \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "venues",
    "multiPolygon": {
      "coordinates": [
        [[[13.36,52.51],[13.42,52.51],[13.42,52.53],[13.36,52.53],[13.36,52.51]]],
        [[[2.34,48.85],[2.36,48.85],[2.36,48.87],[2.34,48.87],[2.34,48.85]]]
      ]
    }
  }'

Async Bulk Ingest with Job Tracking (v2.9.12+)

JOB=$(curl -s -X POST http://localhost:11023/v1/bulk-ingest-job \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "archive",
    "documents": [ ... tens of thousands of docs ... ],
    "callbackUrl": "https://example.com/webhook"
  }' | jq -r .id)

curl "http://localhost:11023/v1/bulk-ingest-job/$JOB"

curl "http://localhost:11023/v1/bulk-ingest-jobs?collection=archive"

curl -X DELETE "http://localhost:11023/v1/bulk-ingest-job/$JOB"

Vector Search (Semantic Search)

Setup

First, configure an embedding provider:

export MDDB_EMBEDDING_PROVIDER=openai
export MDDB_EMBEDDING_API_KEY=sk-your-key-here

export MDDB_EMBEDDING_PROVIDER=voyage
export MDDB_EMBEDDING_API_KEY=pa-your-key-here

export MDDB_EMBEDDING_PROVIDER=ollama

Adding Documents (auto-embedding)

When an embedding provider is configured, documents are automatically embedded when added:

curl -X POST http://localhost:11023/v1/add \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "docs",
    "key": "auth-guide",
    "lang": "en_US",
    "meta": {"category": ["security"], "type": ["guide"]},
    "contentMd": "# Authentication Guide\n\nThis guide covers user authentication using JWT tokens. Learn how to implement login, registration, and session management."
  }'

curl -X POST http://localhost:11023/v1/add \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "docs",
    "key": "api-reference",
    "lang": "en_US",
    "meta": {"category": ["api"], "type": ["reference"]},
    "contentMd": "# API Reference\n\nComplete REST API reference with endpoints, parameters, and response formats."
  }'

curl -X POST http://localhost:11023/v1/add \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "docs",
    "key": "deployment",
    "lang": "en_US",
    "meta": {"category": ["devops"], "type": ["guide"]},
    "contentMd": "# Deployment Guide\n\nHow to deploy the application to production using Docker, Kubernetes, and CI/CD pipelines."
  }'

Semantic Search (finding documents by meaning)

curl -X POST http://localhost:11023/v1/vector-search \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "docs",
    "query": "how to login users",
    "topK": 3,
    "includeContent": true
  }'

Response shows which documents are most relevant and their similarity scores:

{
  "results": [
    {
      "document": {
        "id": "docs|auth-guide|en_us",
        "key": "auth-guide",
        "meta": {"category": ["security"], "type": ["guide"]},
        "contentMd": "# Authentication Guide\n..."
      },
      "score": 0.85,
      "rank": 1
    },
    {
      "document": {
        "id": "docs|api-reference|en_us",
        "key": "api-reference",
        "meta": {"category": ["api"], "type": ["reference"]}
      },
      "score": 0.42,
      "rank": 2
    }
  ],
  "total": 2,
  "model": "text-embedding-3-small",
  "dimensions": 1536
}

Hybrid Search (vector + metadata filter)

Combine semantic search with metadata pre-filtering:

curl -X POST http://localhost:11023/v1/vector-search \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "docs",
    "query": "password reset flow",
    "topK": 5,
    "filterMeta": {"category": ["security"]},
    "includeContent": false
  }'

Search with Similarity Threshold

curl -X POST http://localhost:11023/v1/vector-search \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "docs",
    "query": "kubernetes deployment",
    "topK": 10,
    "threshold": 0.7
  }'

Reindex Existing Documents

If you added documents before configuring embeddings, or changed the model:

curl -X POST http://localhost:11023/v1/vector-reindex \
  -H 'Content-Type: application/json' \
  -d '{"collection": "docs", "force": false}'

curl -X POST http://localhost:11023/v1/vector-reindex \
  -H 'Content-Type: application/json' \
  -d '{"collection": "docs", "force": true}'

Check Embedding Status

curl http://localhost:11023/v1/vector-stats | jq

Response:

{
  "enabled": true,
  "provider": "text-embedding-3-small",
  "model": "text-embedding-3-small",
  "dimensions": 1536,
  "index_ready": true,
  "collections": {
    "docs": {
      "total_documents": 3,
      "embedded_documents": 3
    }
  }
}

Export Examples

NDJSON Export

curl -X POST http://localhost:11023/v1/export \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "format": "ndjson"
  }' > export.ndjson

curl -X POST http://localhost:11023/v1/export \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "filterMeta": {"status": ["published"]},
    "format": "ndjson"
  }' > published.ndjson

ZIP Export

curl -X POST http://localhost:11023/v1/export \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "format": "zip"
  }' > export.zip

Backup & Restore

Creating Backups

curl "http://localhost:11023/v1/backup?to=backup-$(date +%s).db"

curl "http://localhost:11023/v1/backup?to=my-backup.db"

#!/bin/bash
DATE=$(date +%Y-%m-%d)
curl "http://localhost:11023/v1/backup?to=backup-${DATE}.db"

Restoring from Backup

curl -X POST http://localhost:11023/v1/restore \
  -H 'Content-Type: application/json' \
  -d '{"from": "backup-1699296000.db"}'

Maintenance

Truncating Revisions

curl -X POST http://localhost:11023/v1/truncate \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "keepRevs": 5,
    "dropCache": true
  }'

curl -X POST http://localhost:11023/v1/truncate \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "keepRevs": 0,
    "dropCache": true
  }'

Shell Scripts

Bulk Import

#!/bin/bash

for file in posts/*.md; do
  key=$(basename "$file" .md)
  content=$(cat "$file")
  
  curl -X POST http://localhost:11023/v1/add \
    -H 'Content-Type: application/json' \
    -d "{
      \"collection\": \"blog\",
      \"key\": \"$key\",
      \"lang\": \"en_US\",
      \"meta\": {\"category\": [\"blog\"]},
      \"contentMd\": $(echo "$content" | jq -Rs .)
    }"
done

Export and Process

#!/bin/bash

curl -X POST http://localhost:11023/v1/export \
  -H 'Content-Type: application/json' \
  -d '{"collection": "blog", "format": "ndjson"}' | \
  jq -r '.key + ": " + .meta.category[0]'

Automated Backup

#!/bin/bash

BACKUP_DIR="/backups/mddb"
DATE=$(date +%Y-%m-%d-%H%M%S)
KEEP_DAYS=7

curl "http://localhost:11023/v1/backup?to=${BACKUP_DIR}/backup-${DATE}.db"

find ${BACKUP_DIR} -name "backup-*.db" -mtime +${KEEP_DAYS} -delete

Integration Examples

Node.js Client

// mddb-client.js
const axios = require('axios');

class MDDBClient {
  constructor(baseURL = 'http://localhost:11023') {
    this.client = axios.create({ baseURL });
  }

  async add(collection, key, lang, meta, contentMd) {
    const response = await this.client.post('/v1/add', {
      collection, key, lang, meta, contentMd
    });
    return response.data;
  }

  async get(collection, key, lang, env = {}) {
    const response = await this.client.post('/v1/get', {
      collection, key, lang, env
    });
    return response.data;
  }

  async search(collection, filterMeta = {}, options = {}) {
    const response = await this.client.post('/v1/search', {
      collection,
      filterMeta,
      ...options
    });
    return response.data;
  }
}

// Usage
const mddb = new MDDBClient();

await mddb.add('blog', 'hello', 'en_US', 
  { category: ['blog'] }, 
  '# Hello World'
);

const doc = await mddb.get('blog', 'hello', 'en_US');
console.log(doc);

Python Client

import requests

class MDDBClient:
    def __init__(self, base_url='http://localhost:11023'):
        self.base_url = base_url
    
    def add(self, collection, key, lang, meta, content_md):
        response = requests.post(f'{self.base_url}/v1/add', json={
            'collection': collection,
            'key': key,
            'lang': lang,
            'meta': meta,
            'contentMd': content_md
        })
        return response.json()
    
    def get(self, collection, key, lang, env=None):
        response = requests.post(f'{self.base_url}/v1/get', json={
            'collection': collection,
            'key': key,
            'lang': lang,
            'env': env or {}
        })
        return response.json()
    
    def search(self, collection, filter_meta=None, **options):
        response = requests.post(f'{self.base_url}/v1/search', json={
            'collection': collection,
            'filterMeta': filter_meta or {},
            **options
        })
        return response.json()

mddb = MDDBClient()

mddb.add('blog', 'hello', 'en_US', 
         {'category': ['blog']}, 
         '# Hello World')

doc = mddb.get('blog', 'hello', 'en_US')
print(doc)

Go Client

// mddb_client.go
package main

import (
    "bytes"
    "encoding/json"
    "net/http"
)

type MDDBClient struct {
    BaseURL string
}

func (c *MDDBClient) Add(collection, key, lang string, meta map[string][]string, contentMd string) (map[string]interface{}, error) {
    data := map[string]interface{}{
        "collection": collection,
        "key": key,
        "lang": lang,
        "meta": meta,
        "contentMd": contentMd,
    }
    
    body, _ := json.Marshal(data)
    resp, err := http.Post(c.BaseURL+"/v1/add", "application/json", bytes.NewBuffer(body))
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    return result, nil
}

// Usage
func main() {
    client := &MDDBClient{BaseURL: "http://localhost:11023"}

    doc, _ := client.Add("blog", "hello", "en_US",
        map[string][]string{"category": {"blog"}},
        "# Hello World")

    fmt.Println(doc)
}

Schema Validation

Schema validation enforces structure on document metadata per collection. It is opt-in -- collections without a schema accept any metadata.

Setting Up a Schema

curl -X POST http://localhost:11023/v1/schema/set \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "products",
    "schema": {
      "required": ["sku", "price", "category"],
      "properties": {
        "sku":      { "type": "string", "pattern": "^SKU-[0-9]+$" },
        "price":    { "type": "number" },
        "category": { "type": "string", "enum": ["electronics", "clothing", "books"] },
        "tags":     { "type": "string", "minItems": 1, "maxItems": 10 }
      }
    }
  }'

Adding Documents with Validation

curl -X POST http://localhost:11023/v1/add \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "products",
    "key": "laptop-1",
    "lang": "en_US",
    "meta": {
      "sku": ["SKU-10042"],
      "price": ["999.99"],
      "category": ["electronics"],
      "tags": ["laptop", "computer", "portable"]
    },
    "contentMd": "# Laptop Pro 15\n\nHigh-performance laptop."
  }'

curl -X POST http://localhost:11023/v1/add \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "products",
    "key": "bad-product",
    "lang": "en_US",
    "meta": {
      "sku": ["INVALID"],
      "category": ["furniture"]
    },
    "contentMd": "# Bad Product"
  }'

Dry-Run Validation

curl -X POST http://localhost:11023/v1/validate \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "products",
    "meta": {
      "sku": ["SKU-20001"],
      "price": ["49.99"],
      "category": ["books"]
    }
  }'

Listing and Managing Schemas

curl -X POST http://localhost:11023/v1/schema/list \
  -H 'Content-Type: application/json' \
  -d '{}'

curl -X POST http://localhost:11023/v1/schema/get \
  -H 'Content-Type: application/json' \
  -d '{"collection": "products"}'

curl -X POST http://localhost:11023/v1/schema/delete \
  -H 'Content-Type: application/json' \
  -d '{"collection": "products"}'

Blog Schema Example

curl -X POST http://localhost:11023/v1/schema/set \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "schema": {
      "required": ["category", "author", "status"],
      "properties": {
        "category": { "type": "string", "enum": ["blog", "tutorial", "news", "changelog"] },
        "author":   { "type": "string" },
        "status":   { "type": "string", "enum": ["draft", "published", "archived"] },
        "tags":     { "type": "string", "maxItems": 5 },
        "featured": { "type": "boolean", "maxItems": 1 }
      }
    }
  }'

curl -X POST http://localhost:11023/v1/add \
  -H 'Content-Type: application/json' \
  -d '{
    "collection": "blog",
    "key": "schema-validation-guide",
    "lang": "en_US",
    "meta": {
      "category": ["tutorial"],
      "author": ["Jane Doe"],
      "status": ["published"],
      "tags": ["mddb", "validation", "schema"],
      "featured": ["true"]
    },
    "contentMd": "# Schema Validation Guide\n\nLearn how to validate document metadata."
  }'

Security & Compliance (v2.9.15+)

Worked examples for the ISO 27001 / SOC 2 hardening features. See SECURITY.md for the full compliance map and config.md for every environment variable.

Enable the audit log and query events by actor

export MDDB_AUTH_ENABLED=true
export MDDB_AUTH_JWT_SECRET=$(openssl rand -hex 32)
export MDDB_AUTH_ADMIN_USERNAME=admin
export MDDB_AUTH_ADMIN_PASSWORD=changeme
export MDDB_AUDIT_ENABLED=true
export MDDB_AUDIT_RETENTION_DAYS=365
./mddbd &

ADMIN_JWT=$(curl -s -X POST http://localhost:11023/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"changeme"}' | jq -r .token)

curl -s -X POST http://localhost:11023/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","password":"wrong"}'

curl -s -H "Authorization: Bearer $ADMIN_JWT" \
  "http://localhost:11023/v1/audit?actor=alice&result=fail&limit=50" | jq .

Flip MDDB_PRODUCTION=true with all guardrails set


export MDDB_PRODUCTION=true
export MDDB_AUTH_ENABLED=true
export MDDB_AUTH_JWT_SECRET=$(openssl rand -hex 32)      # >= 32 bytes
export MDDB_TLS_ENABLED=true
export MDDB_TLS_CERT=/etc/mddb/server.crt
export MDDB_TLS_KEY=/etc/mddb/server.key
export MDDB_CORS_ORIGIN=https://app.example.com          # not "*"
export MDDB_AUDIT_ENABLED=true
export MDDB_RATE_LIMIT_ENABLED=true

./mddbd

curl -s http://localhost:11023/v1/compliance-status | jq .

Trigger the rate limiter and read 429 + Retry-After

export MDDB_RATE_LIMIT_ENABLED=true
export MDDB_RATE_LIMIT_REQUESTS=10
export MDDB_RATE_LIMIT_WINDOW=60
export MDDB_RATE_LIMIT_BURST=5
export MDDB_RATE_LIMIT_BY=ip
./mddbd &

for i in $(seq 1 20); do
  printf "req %02d -> " "$i"
  curl -s -o /dev/null -w "HTTP %{http_code}  X-RateLimit-Remaining=%header{x-ratelimit-remaining}  Retry-After=%header{retry-after}\n" \
    http://localhost:11023/v1/stats
done

Encrypt a collection end-to-end and verify ciphertext on disk

export MDDB_ENCRYPTION_KEY="$(openssl rand -base64 32)"
./mddbd &

curl -s -X PUT http://localhost:11023/v1/collection-config \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{"collection":"secrets","encrypted":true}'

curl -s -X POST http://localhost:11023/v1/add \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{"collection":"secrets","key":"api-key-1","lang":"en_US",
       "contentMd":"# Production API key\nsk-live-XXXXXXXXXXXX"}'

curl -s -X POST http://localhost:11023/v1/get \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{"collection":"secrets","key":"api-key-1","lang":"en_US"}' | jq -r .contentMd

strings mddb.db | grep -a MDDB_ENC_V1 | head -3

Subscribe to security.auth_failure_burst and trigger it

export MDDB_INCIDENT_AUTH_THRESHOLD=5
export MDDB_INCIDENT_AUTH_WINDOW_SEC=30
export MDDB_INCIDENT_AUTH_COOLDOWN_SEC=60
./mddbd &

curl -s -X POST http://localhost:11023/v1/webhooks \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://webhook.site/your-unique-id",
    "events": ["security.auth_failure_burst"]
  }'

for i in $(seq 1 10); do
  curl -s -o /dev/null -X POST http://localhost:11023/v1/auth/login \
    -H "Content-Type: application/json" \
    -d '{"username":"alice","password":"wrong"}'
done

#