BETA — open for public testing

Pop-Search

Structured Similarity & Anomaly Engine

Load your catalog — products, transactions, sensor readings — as plain records. Get similar records and statistical outliers back, directly on your raw numeric fields. No vectors. No models. No pipeline.

Vector-less Interpretable scores Single binary, single node Runs on 2-core / 4 GB Self-hosted

What it is

A new kind of search: similarity without vectors

Pop-Search is a structured similarity & anomaly engine. You load your data as ordinary records, and it finds records that are similar to a given one, and records that are statistically out of place — using the fields you already have.

The whole idea in one line: vector-less search. A vector database needs you to train an embedding model, push every record through it, and accept a black box. Pop-Search skips all of that. Your numeric fields already carry meaning — price, rating, latency, temperature — so it works on them directly.

Every similarity result comes with a score you can read and a reason you can explain, which matters when the answer has to stand up in a pricing review, a fraud queue, or a maintenance ticket.

How it works

Load it. Query it. It runs on a shoe-string.

You load your data. Pop-Search indexes your numeric fields so that similarity, range filtering, and anomaly detection all run fast — even on a small 2-core / 4 GB server.

01

Ingest

Load records as JSON or bulk CSV. Define which fields are numeric and which are categorical.

02

Index

Pop-Search indexes your numeric fields for fast similarity, range, and anomaly lookups.

03

Query

Search with ranges + filters, find similar records, and detect outliers — over HTTP, with interpretable results.

⚖ The algorithm is patent pending

We can't share the internals just yet. The short version: it's deterministic, interpretable, and vector-less — and it's built to stay fast on modest hardware. This is a beta, open for public testing of the algorithm. What you see here is what we can show today; the details are on the way.

What you get

Everything the "find similar + find outliers" job needs

🎯

Similar records

Nearest records by field proximity, each with an interpretable 0–1 score.

🚩

Anomaly detection

Statistical outliers per numeric field, with a z-score you can threshold and explain.

🧮

Fast filtering

Numeric ranges + categorical equality, combined with AND / OR / must-not.

📊

Facets & aggregations

Group your matches by any field to see the shape of the result set.

🏷️

Field labels

Attach human-readable labels to your numeric fields and query by them.

🔐

Multi-tenant

Isolated collections per API key. One server, many customers.

📦

Self-hosted, single node

One static binary. Local file persistence. No external database, no cluster.

📥

CSV + JSON ingest

Bulk CSV (optionally gzip) or streaming JSON. Update, delete, compact.

Why it's different

Not a vector DB. Not a text search engine.

The tools people reach for today were built for a different job.

Vector DB
(Qdrant / Milvus)
Search engine
(Elastic / Meili)
Postgres / SQLPop-Search
Needs embeddings?Yespgvector: yespgvector: yesNo
Needs a model / GPUYesOptionalOptionalNo
Numeric-field similarityVia vectorsNoHand-rolled SQLNative
Anomaly / outlier detectionNoNoHand-rolledNative
Interpretable resultsBlack boxText relevanceYou defineYes
Runs on 2-core / 4 GBHardYesYesYes

Hardware

Built for the box you already have

The entire engine is one static binary with local file persistence. It runs comfortably on a small VPS — the kind of box that hosts a dozen little services — with no JVM, no cluster, no external database, and no GPU.

2
vCPU
4 GB
RAM
40 GB
disk
1
binary, single node

That's the whole footprint — and there's still room for the rest of the stack.

Quick start

Five calls to a working demo

Base URL is the host serving this page (the API serves its own docs, so the playground and the API are the same origin). With auth enabled, send your key in the X-Pop-Api-Key header.

1. Create a collection — declare your fields.

curl -s $BASE/collections -H 'Content-Type: application/json' -d '{
  "name": "products",
  "fields": {
    "price":    { "type": "numeric", "min": 0.99, "max": 10000, "bins": 20, "log": true },
    "rating":   { "type": "numeric", "min": 0, "max": 5, "bins": 16 },
    "category": { "type": "categorical", "levels": ["electronics","furniture","outdoor","kitchen"] }
  }
}'

2. Ingest records (JSON array, or POST /collections/products/ingest/csv for bulk).

curl -s $BASE/collections/products/records -H 'Content-Type: application/json' -d '[
  { "id": "e1", "price": 249.99, "rating": 4.6, "category": "electronics" },
  { "id": "e2", "price": 89.99,  "rating": 4.2, "category": "electronics" }
]'

3. Search — numeric range + categorical filter, ANDed.

curl -s $BASE/collections/products/search -H 'Content-Type: application/json' -d '{
  "must": [ { "field": "price", "gte": 50, "lte": 500 }, { "field": "category", "eq": "electronics" } ],
  "limit": 20, "with_values": true
}'

4. Find similar — nearest records to a given one.

curl -s $BASE/collections/products/similar -H 'Content-Type: application/json' -d '{
  "record": { "price": 249.99, "rating": 4.6, "category": "electronics" },
  "k": 10, "with_values": true
}'

5. Detect anomalies — statistical outliers on a field.

curl -s $BASE/collections/products/anomalies -H 'Content-Type: application/json' -d '{
  "field": "price", "z": 2.5, "limit": 50
}'

Live playground

Try it right here

No account, no setup. The button below loads a 45-product catalog into this server (collection demo) and you query it live. It's the exact API from the docs — the playground just calls it from your browser.

Click “Load sample catalog” to start.

Find similar

Pick a product; we return its nearest neighbours by field proximity (interpretable score).

Price outliers

Statistical anomalies on the price field. Three products are deliberately mispriced — can you catch all of them? Lower the z-threshold to widen the net.

Filtered search

Numeric range + categorical filter, ANDed — the core “range + AND/OR” query.

API reference

Every endpoint

JSON in, JSON out. All query endpoints take a JSON body. Errors return a JSON { "error": "..." } with an appropriate HTTP status.

MethodEndpointWhat it does
POST/collectionsCreate a collection from a field spec
GET/collectionsList collections for the caller
GET/collections/{name}Collection stats (record count, per-field bins)
DEL/collections/{name}Delete a collection
POST/collections/{name}/recordsIngest a JSON array of records
GET/collections/{name}/records/{id}Get one record by id
PATCH/collections/{name}/records/{id}Update a record's fields
DEL/collections/{name}/records/{id}Delete one record
POST/collections/{name}/ingest/csvBulk CSV ingest (plain or gzip)
POST/collections/{name}/searchRange + AND/OR/must-not query, facets, sort
POST/collections/{name}/similarNearest records to a given record (scored)
POST/collections/{name}/anomaliesStatistical outliers on a numeric field
PUT/collections/{name}/labelsSet human labels for a numeric field's ranges
GET/collections/{name}/labelsGet field labels
DEL/collections/{name}/labelsRemove field labels
POST/collections/{name}/relearnRebuild field stats after a data shift
POST/collections/{name}/compactReclaim space from deleted records
GET/health · /status · /metricsOperational endpoints

Query conditions support gte / lte (numeric range), eq / neq / in (exact or set), label (field label), anomaly (z-threshold), and exists (optional fields). Combine with must (AND), any (OR), must_not (exclude).

Feedback

Report a bug or request a feature