Skip to content

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Percona Release Notes Search

Demo app for Percona Vector Search for MongoDB (mongot). Upload Percona product release notes in Markdown format and search them with:

  • Text search — Atlas-compatible $search powered by mongot
  • Vector search — semantic $vectorSearch using embeddings generated by a local Ollama model (nomic-embed-text, 768 dimensions)

Both modes include an AI-generated summary of the most relevant findings (local Ollama chat model), keyword highlighting in results, and a query inspector showing the exact mongosh-ready queries that were executed.

Architecture

┌──────────────────────┐   nginx :8080   ┌──────────────────────────────────┐
│  Angular 22 (SPA)    │  ─────────────► │  Express API  (server/)          │
│  Search + Upload UI  │  /api/* proxied │  POST /api/upload                │
└──────────────────────┘                 │  POST /api/search (text/vector)  │
                                         │  GET  /api/documents             │
                                         │  POST /api/embeddings/update     │
                                         │  GET  /api/embeddings/status     │
                                         │  GET  /api/health                │
                                         └────────┬─────────────────────────┘
                                                  │
                               ┌──────────────────┼────────────────────┐
                               │                  │                    │
                    ┌──────────▼───────┐  ┌───────▼──────┐  ┌─────────▼──────────┐
                    │  mongod :27017   │  │  mongot      │  │  Ollama :11434     │
                    │  searchIndexMgmt │  │  gRPC :27028 │  │  nomic-embed-text  │
                    └──────────────────┘  │  metrics:9946│  │  llama3.2:1b (chat)│
                                          └──────────────┘  └────────────────────┘

Running with Docker Compose

Two compose files are provided — pick the stack you want to run. Both include an Ollama sidecar whose one-shot ollama-init companion pulls nomic-embed-text (~274 MB) and llama3.2:1b (~1.3 GB) on first startup, then warms the chat model into memory so the first search doesn't stall on model load. Models stay loaded indefinitely (OLLAMA_KEEP_ALIVE: -1) — inference runs CPU-only inside Docker, and reloading the chat model from disk would otherwise add ~30–60 s to the first search after every idle period.

Community stack (MongoDB Community + mongot)

One-time setup:

# 1. Password file — mongot requires owner-readable only (0600)
cp pwfile.example pwfile && chmod 600 pwfile

# 2. Keyfile — required by MongoDB for intra-replica-set auth (0400)
openssl rand -base64 756 > keyfile && chmod 400 keyfile
# Production / normal run
docker compose -f docker-compose.community.yml up -d --build

# Development — live reload on file changes
docker compose -f docker-compose.community.yml watch
Service Image Port
mongod mongodb/mongodb-community-server:latest 27017
mongot mongodb/mongodb-community-search:latest 27028
ollama ollama/ollama:latest 11434
api built from server/ 3000 (internal)
app built from project root 8080

Percona stack (Percona Server for MongoDB 8.3 + Percona mongot)

One-time setup (same files as the community stack):

# 1. Password file — mongot requires owner-readable only (0600)
cp pwfile.example pwfile && chmod 600 pwfile

# 2. Keyfile — required by MongoDB for intra-replica-set auth (0400)
openssl rand -base64 756 > keyfile && chmod 400 keyfile
# Production / normal run
docker compose -f docker-compose.percona.yml up -d --build

# Development — live reload on file changes
docker compose -f docker-compose.percona.yml watch
Service Image Port
mongod perconalab/percona-server-mongodb:8.3.0-1 27017
mongot perconalab/percona-server-mongodb-mongot:0.50.0 27028 (gRPC), 9946 (metrics)
search-init perconalab/percona-server-mongodb:8.3.0-1 — (one-shot)
ollama ollama/ollama:latest 11434
api built from server/ 3000
app built from project root 8080

On first run the mongod entrypoint bootstraps the replica set and creates the root and mongotUser users, then the one-shot search-init service creates the two search indexes the API expects (default and vector_index) — no manual index setup is needed. It is idempotent, so re-running the stack is safe.

Open the app

http://localhost:8080

Docker Compose Watch (live reload)

docker compose watch keeps the stack running and reacts to file changes automatically:

Service Trigger Action
api server/src/** sync+restart — files are copied into the container; the server restarts without rebuilding the image
api server/package.json rebuild — reinstalls dependencies and rebuilds the image
app src/**, public/**, angular.json, package.json rebuild — Angular is compiled ahead-of-time, so a full image rebuild is required
docker compose -f docker-compose.community.yml watch

The api sync+restart cycle is near-instant. The app rebuild takes ~30–60 s depending on machine speed (Angular AOT compile + nginx image layer).

Useful commands

# Tail logs for all services
docker compose -f docker-compose.community.yml logs -f

# Tail logs for a single service
docker compose -f docker-compose.community.yml logs -f api

# Check Ollama model status
docker exec ollama-community ollama list

# Stop and remove containers (keeps volumes)
docker compose -f docker-compose.community.yml down

# Stop and remove containers AND volumes (full reset)
docker compose -f docker-compose.community.yml down -v

# Open a mongosh session against the community stack
docker exec -it mongod-community \
  mongosh -u root -p password --authenticationDatabase admin

502 Bad Gateway after recreating the api container? nginx in the app container resolves the api hostname once at startup, so a recreated API container with a new IP leaves nginx pointing at the old one. Fix with docker restart percona-rn-search-app-percona (or …-community).

Create the search indexes

Percona stack: skip this section — the search-init service creates both indexes automatically (see init-search-indexes-percona.sh).

For the community stack (or any manual setup), run these once after the stack is up — mongot needs index definitions before $search and $vectorSearch queries work. Without them, search queries succeed but return zero results (mongot logs No index in catalog).

Text search index:

use release_notes

db.documents.createSearchIndex("default", { mappings: { dynamic: true } })

Dynamic mapping covers every field the API searches (content, releaseHighlights.title, releaseHighlights.content, newFeatures.description, improvements.description, bugFixes.description).

Vector search index (required for semantic search):

db.documents.createSearchIndex(
  "vector_index",
  "vectorSearch",
  {
    fields: [
      {
        type: "vector",
        path: "embedding",
        numDimensions: 768,
        similarity: "cosine",
      },
      {
        type: "filter",
        path: "product",
      },
    ]
  }
)

Note: if an index does not exist, mongot returns an empty result set rather than an error — so $search/$vectorSearch appear to "work" but find nothing. If the $search query itself fails (e.g. mongot is down), the API falls back to a $text index lookup and then to a regex scan. For vector search, also make sure embeddings have been generated (see below).


Running locally (without Docker)

0. Ollama

Install Ollama and pull the required models:

ollama pull nomic-embed-text   # embeddings (vector search)
ollama pull llama3.2:1b        # chat model (AI summary + keyword extraction)

Any other chat model already on your Ollama instance works too — set OLLAMA_CHAT_MODEL in server/.env to override the default. The Docker stacks use llama3.2:1b because inference is CPU-only inside Docker; running Ollama natively (with GPU acceleration) makes larger models like llama3.2 (3B) practical, with better keyword extraction quality.

1. Backend

cd server
cp .env.example .env     # set MONGODB_URI and OLLAMA_URL
npm install
npm run dev              # http://localhost:3000

Environment variables:

Variable Default Description
MONGODB_URI (required) mongodb://… URI for Percona Server for MongoDB
MONGODB_DB release_notes Database name
MONGODB_COLLECTION documents Collection name
PORT 3000 HTTP port
OLLAMA_URL http://localhost:11434 Ollama base URL
OLLAMA_EMBED_MODEL nomic-embed-text Ollama model used for generating embeddings
OLLAMA_CHAT_MODEL llama3.2 Ollama chat model used for AI summaries and keyword extraction (the Docker stacks set llama3.2:1b)

2. Frontend

npm install
npm start                # http://localhost:4200

Node.js ≥ 24.15.0 is required by Angular CLI 22.

The dev server proxies /api/* to http://localhost:3000 automatically via the environment.development.ts apiUrl.


Usage

Uploading documents

Go to /upload, drag & drop one or more .md release notes files.
Filename convention: <version>.md (e.g. 7.0.18-11.md).
The product name is auto-detected from the H1 heading.
Embeddings are generated automatically at upload time if Ollama is reachable.

Generating / updating embeddings

After uploading documents (or if Ollama was unavailable during upload), go to /upload and use the Embeddings panel:

  • Update missing — generates embeddings only for documents that don't have one yet
  • Regenerate all — re-embeds every document (useful after switching models)

The panel shows how many documents currently have embeddings vs. the total, and whether Ollama is reachable.

Searching

Go to /search and type a natural language query. Use the Text / Vector toggle to choose the search mode:

Mode Powered by When to use
Text mongot $search Keyword and fuzzy matching
Vector mongot $vectorSearch + Ollama Semantic / conceptual queries

AI summary

After a search (text or vector), an AI Summary panel appears above the result cards. The local Ollama chat model (llama3.2:1b in the Docker stacks) reads the top matching release notes and writes a short, conversational answer that highlights the findings most relevant to your query. The summary is generated entirely on-device — no data leaves your machine. If Ollama is unavailable or times out, the panel shows the reason instead.

Expect ~15–20 s per search in the Docker stacks: the summary and keyword extraction run on CPU. The nginx proxy allows up to 180 s (proxy_read_timeout in nginx.conf) before giving up on the API.

Keyword highlighting

Matched terms are highlighted in the result cards. Keywords are extracted from your query by the Ollama chat model, which also expands common Percona abbreviations (e.g. PSMDBPercona Server for MongoDB, PBMPercona Backup for MongoDB) so both forms light up.

Query inspector

Each search response includes the exact queries that were executed ($search / $vectorSearch aggregations, plus any fallbacks). Expand the MongoDB queries panel under the search box to copy them as mongosh-ready snippets for verification or troubleshooting.

Server status

The header shows a live status indicator for the backend API (polled via GET /api/health), so you can tell at a glance whether the stack is up.

Example queries:

  • "bug fix to LDAP"
  • "Google Workload Federation"
  • "audit log improvements in 7.0"
  • "performance regression in replication" ← vector search shines here

Filter by product using the dropdown. Results show a relevance score and are ranked by it.


Supported products

  • Percona Server for MongoDB
  • Percona Backup for MongoDB
  • Percona Operator for MongoDB
  • Percona ClusterSync for MongoDB

About

Percona Vector Search sample demo app to query Percona Release Notes

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages