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.

The /search endpoint is Mindloom’s primary discovery surface. It supports two fundamentally different retrieval strategies: semantic mode, which encodes your query into a 384-dimensional embedding via the inference service and ranks results using VECTOR_DISTANCE(COSINE) in Oracle, and keyword mode, which falls back to a plain SQL LIKE scan against title and body — no inference call, no vector math, no ranked similarity. Both modes return the same SearchResponse envelope, but their internal behavior, performance characteristics, and edge-case semantics differ enough that you should treat them as distinct operations that happen to share a route.

Endpoint

GET /search

Query Parameters

q
string
required
The search query string. A blank or whitespace-only value returns 400 VALIDATION_ERROR immediately — the controller validates this before dispatching to either search service.
mode
string
default:"semantic"
Controls the retrieval strategy. Accepted values (case-insensitive): semantic or keyword. Any other value returns 400 VALIDATION_ERROR with the message "Modo de búsqueda inválido: '…'. Use 'semantic' o 'keyword'".
category
string
Optional category filter. Behavior differs by mode — see the Mode Behavior section and the warning below before relying on this parameter in keyword mode.
page
integer
default:"0"
Zero-based page index used to calculate the SQL OFFSET (offset = page × size).
size
integer
default:"10"
Number of results per page (FETCH NEXT :limit ROWS ONLY).

Mode Behavior

Semantic mode (mode=semantic)

  1. The API calls the inference service’s POST /embed endpoint with the query and type=query. The E5 model internally prepends "query: " to the text before encoding.
  2. The resulting 384-float, L2-normalised vector is serialised to 1536 bytes and passed to Oracle.
  3. If category is provided, the query runs semanticSearchWithCategory — a dedicated native query with a WHERE category = :category clause. Without it, semanticSearch is used (no category filter).
  4. Results are ordered ascending by VECTOR_DISTANCE (descending similarity). elapsedMs reflects real wall-clock time.
Oracle query (with category):
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

Keyword mode (mode=keyword)

  1. No call is made to the inference service.
  2. The API executes a native SQL LIKE scan: WHERE title LIKE %:q% OR body LIKE %:q%.
  3. Every result receives a fixed similarity of 1.0 — there is no ranking.
  4. elapsedMs is always 0 (hardcoded).
Oracle query:
SELECT id, title, category FROM contents
WHERE title LIKE %:q% OR body LIKE %:q%
Category is not a filter in keyword mode. When category is provided alongside mode=keyword, the keyword service concatenates the category value to the query string before the LIKE scan:
// KeywordSearchService — not a column filter
String query = q;
if (category != null && !category.isBlank()) {
    query = q + " " + category;
}
?q=spring&category=Backend&mode=keyword searches for the literal string "spring Backend" inside title and body — almost always returning zero results. If you need to filter by category and search by keyword, you must handle the category filtering on the client side.

Response — 200 OK

SearchResponse
mode
string
The search mode that was used: "semantic" or "keyword".
total
number
The number of results returned in this page (results.size()), not the total hit count in the corpus.
elapsedMs
number
Wall-clock time of the search operation in milliseconds. Real in semantic mode; always 0 in keyword mode.
results
object[]
The list of matched content items for this page.
total is the page size, not the corpus hit count. It is computed from results.size(), so with size=10 and 500 matching documents, total returns 10. Do not use total to calculate the number of pages or display a total-results count — it will always equal size on full pages.

Error Codes

HTTP Statuserror fieldCause
400VALIDATION_ERRORq is empty or blank, or mode is not "semantic" or "keyword"
503INTERNAL_ERRORThe database is not configured (app.database.enabled=true is required), or the inference service is unreachable during mode=semantic (the /embed call failed)
Error response envelope:
{
  "error": "VALIDATION_ERROR",
  "message": "El parámetro 'q' no puede estar vacío",
  "timestamp": "2024-11-18T14:22:03.441Z"
}

Examples

Semantic search with category filter

curl 'http://localhost:8080/search?q=apis+rest+en+java&mode=semantic&category=Backend'
{
  "mode": "semantic",
  "total": 2,
  "elapsedMs": 143,
  "results": [
    {
      "id": "devto-4821",
      "title": "Intro to Spring Boot",
      "category": "Backend",
      "similarity": 0.8641
    },
    {
      "id": "so-78412",
      "title": "Cómo paginar con Spring Data JPA",
      "category": "Backend",
      "similarity": 0.8117
    }
  ]
}
curl 'http://localhost:8080/search?q=spring+boot&mode=keyword'
{
  "mode": "keyword",
  "total": 3,
  "elapsedMs": 0,
  "results": [
    {
      "id": "devto-4821",
      "title": "Intro to Spring Boot",
      "category": "Backend",
      "similarity": 1.0
    },
    {
      "id": "so-78412",
      "title": "Cómo paginar con Spring Data JPA",
      "category": "Backend",
      "similarity": 1.0
    },
    {
      "id": "devto-9034",
      "title": "Spring Boot Auto-configuration Explained",
      "category": "Backend",
      "similarity": 1.0
    }
  ]
}

400 — blank query

curl 'http://localhost:8080/search?q=&mode=semantic'
{
  "error": "VALIDATION_ERROR",
  "message": "El parámetro 'q' no puede estar vacío"
}

400 — invalid mode

curl 'http://localhost:8080/search?q=spring&mode=fuzzy'
{
  "error": "VALIDATION_ERROR",
  "message": "Modo de búsqueda inválido: 'fuzzy'. Use 'semantic' o 'keyword'"
}

Build docs developers (and LLMs) love