Skip to main content

Text Search

Text search is an opt-in mode for querying free-text content inside process variables. It is activated by including a text object in the request body alongside (or instead of) a structured filter.

{
"filter": { "variables.loan_status": "in_review" },
"text": {
"query": "compliance review",
"mode": "fulltext",
"fields": ["variables.notes", "variables.review_comments"]
}
}

Modes

fulltext (default)

Uses PostgreSQL native full-text search. This mode:

  • Handles Portuguese (PT-BR) correctly, including accent normalization — searching "revisão" matches "revisões"
  • Matches word stems
  • Is efficient when used with specific fields
{
"text": {
"query": "fraude suspeita",
"mode": "fulltext",
"fields": ["variables.notes"]
}
}

trigram

Uses PostgreSQL pg_trgm for similarity-based matching. This mode:

  • Tolerates typos and partial matches — "samsumg" matches "Samsung"
  • Does not stem words — matches character sequences
  • Is slightly more expensive than fulltext
{
"text": {
"query": "samsumg",
"mode": "trigram",
"fields": ["variables.product_name"]
}
}

Setting "fuzzy": true is shorthand for mode: "trigram" with the default similarity threshold.

fields

The fields array specifies which variable paths to search. When omitted, the search runs over all string-type variables — which is significantly more expensive and should be avoided on large datasets.

{
"text": {
"query": "example",
"fields": ["variables.notes", "variables.description"]
}
}

Maximum: 20 fields per query.

Ranking

When sort includes _textRank, results are ordered by relevance score (fulltext mode only):

{
"text": { "query": "revisão urgente", "mode": "fulltext", "fields": ["variables.notes"] },
"sort": { "_textRank": -1 }
}

Mode availability

mode: "trigram" requires the pg_trgm PostgreSQL extension. If unavailable, the endpoint returns 400 with a message explaining how to enable it. mode: "fulltext" is always available.

Combining with structured filters

Text and structured filters can be combined — results must satisfy both:

{
"filter": {
"variables.status": "in_review",
"startedAt": { "$gte": "2026-01-01T00:00:00Z" }
},
"text": {
"query": "fraude",
"fields": ["variables.notes"]
}
}