Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/No-Country-simulation/G9-LATAM-Team-58/llms.txt

Use this file to discover all available pages before exploring further.

Mindloom’s search endpoint exposes two fundamentally different strategies behind a single URL. Semantic mode converts your query into a 384-dimensional embedding and asks Oracle to rank every stored document by cosine distance — surfacing results that share meaning even when they share no words. Keyword mode bypasses the inference service entirely and falls back to a SQL LIKE scan, trading recall and ranking for simplicity and zero latency overhead. Both modes are accessed via GET /search?q=…, but their behaviour, filtering logic, and response metadata differ in ways that matter when you build on top of them.

The two search modes

Semantic search (default)

When mode=semantic (or when mode is omitted), the API calls the inference service’s /embed endpoint to convert the query into a vector, then runs VECTOR_DISTANCE(COSINE) against every stored embedding in Oracle ADB. Step-by-step flow:
1

Query embedding — /embed

The API POSTs to the inference service with type=query so the E5 model applies its "query: " prefix before encoding:
{ "text": "apis rest en java", "type": "query" }
The type field must be "query" for searches and "passage" for document ingestion. Sending type=passage in a search request returns worse results with no error — the E5 model applies the wrong prefix silently, degrading recall without any log entry.
2

Vector distance query in Oracle

The 384 floats are serialised to a bracket-delimited string via VectorUtils.toVectorString(), then passed into TO_VECTOR(?, 384, FLOAT32) in the query, with optional category filtering:
-- Without category filter
SELECT id, title, category,
       1 - VECTOR_DISTANCE(embedding, TO_VECTOR(:queryEmbedding, 384, FLOAT32), COSINE) AS similarity
FROM contents
ORDER BY VECTOR_DISTANCE(embedding, TO_VECTOR(:queryEmbedding, 384, FLOAT32), COSINE)
OFFSET :offset ROWS FETCH NEXT :limit ROWS ONLY;

-- With category filter (a separate named query, not an optional WHERE clause)
SELECT id, title, category,
       1 - VECTOR_DISTANCE(embedding, TO_VECTOR(:queryEmbedding, 384, FLOAT32), COSINE) AS similarity
FROM contents
WHERE category = :category
ORDER BY VECTOR_DISTANCE(embedding, TO_VECTOR(:queryEmbedding, 384, FLOAT32), COSINE)
OFFSET :offset ROWS FETCH NEXT :limit ROWS ONLY;
3

Response with real similarity scores

Results are returned pre-sorted descending by similarity (1.0 = identical, ~0 = unrelated). elapsedMs reflects actual wall-clock time for the embedding call plus the vector query.

Keyword search (mode=keyword)

Keyword mode never calls the inference service. It runs a SQL LIKE scan across the title and body columns:
SELECT id, title, category FROM contents WHERE title LIKE %:q% OR body LIKE %:q%
When mode=keyword, the category parameter is not applied as a column filter. The service concatenates it to the search string instead: ?q=spring&category=Backend searches for the literal string "spring Backend" inside title and body. This almost always returns zero results. Category filtering only works correctly in mode=semantic.
In keyword mode, similarity is hardcoded to 1.0 for all results (there is no ranking), and elapsedMs is hardcoded to 0.

Mode comparison

Featuresemantickeyword
Uses inference serviceYes (/embed)No
Category filterWHERE category = :category column filterConcatenated to the query string
similarity fieldReal cosine score (0–1)Fixed 1.0
elapsedMsReal wall-clock millisecondsFixed 0
Finds synonyms / paraphrasesYesNo
Result orderingBy semantic similarityUnspecified (DB default)

Request parameters

ParameterDefaultDescription
qrequiredQuery string. Blank value returns 400 VALIDATION_ERROR.
modesemanticsemantic or keyword (case-insensitive). Any other value returns 400.
categoryOptional category filter. Only functions as a column filter in semantic mode.
page0Zero-based page index.
size10Page size.

Example request and response

GET /search?q=apis+rest+en+java&mode=semantic&category=Backend&page=0&size=10
{
  "mode": "semantic",
  "total": 2,
  "elapsedMs": 143,
  "results": [
    {
      "id": "devto-4821",
      "title": "Introducción a Spring Boot",
      "category": "Backend",
      "similarity": 0.8641
    }
  ]
}
total in the response is the page size — it equals results.size(), not the overall number of matching documents. With size=10 and 500 matching items, total will be 10. Do not use total to compute a page count or show a total-results figure; those values require a separate COUNT query that is not currently part of the contract.

Choosing the right mode

Use mode=semantic as your default. It surfaces conceptually related content even when the user’s phrasing differs from the stored text — for example, “database indexing strategies” and “Oracle VECTOR_DISTANCE” will score highly against each other. Reserve mode=keyword only for exact-string lookups where you need to match a specific identifier, package name, or code snippet that would be diluted by semantic similarity scoring.

Response field reference

mode

Echoes the mode used for the query: "semantic" or "keyword". Useful for logging and debugging.

total

The number of results in this page (results.size()). Not the overall hit count. See the note above.

elapsedMs

Wall-clock time in milliseconds for the embedding call plus vector query. Always 0 in keyword mode.

results[].similarity

Cosine similarity as 1 − VECTOR_DISTANCE(…, COSINE). Range 0–1; higher is more similar. Always 1.0 in keyword mode.
For the full parameter reference, error envelope shapes, and pagination behaviour, see the GET /search API reference.

Build docs developers (and LLMs) love