memx://¶
PostgreSQL-protocol component that talks to the memx AI-native database. memx is wire-compatible with PostgreSQL but exposes additional vector / text / hybrid match functions (MATCH_DENSE, MATCH_TEXT, FUSION). The component uses pgx/v5 with a per-endpoint connection pool and supports both producer and consumer (polling) modes.
Use memx:// when you want one backing store that handles row-level data, dense-vector retrieval, BM25-style text retrieval, and reciprocal-rank fusion in a single SQL surface.
URI shape¶
<host> defaults to localhost, <port> defaults to 5432, <database> defaults to memx. All three can also be packed into the dsn param.
Parameters¶
| Param | Type | Default | Producer/Consumer/Both | Description |
|---|---|---|---|---|
(path) host:port/database |
string | localhost:5432/memx |
Both | Server location. |
dsn |
string | derived | Both | Full PostgreSQL DSN. Wins over the path-derived form. The component appends default_query_exec_mode=simple_protocol when absent. |
user |
string | memx |
Both | Username. |
password |
string | — | Both | Password. |
table |
string | — | Both | Target table. Required for insert, vector_search, text_search, hybrid_search. |
operation |
enum | query |
Both | query, insert, vector_search, text_search, hybrid_search. |
topK |
integer | 10 |
Producer | LIMIT for the three search operations. |
column |
string | embedding / content |
Producer | vector_search uses embedding; text_search uses content. Override per call via this param. |
vectorColumn |
string | embedding |
Producer | hybrid_search only — dense-vector column. |
textColumn |
string | content |
Producer | hybrid_search only — text column. |
pollInterval |
duration | 30s |
Consumer | How often the consumer issues SELECT * FROM <table> and dispatches results. |
Operations¶
query (Producer)¶
Body: the SQL string. Executes it with no parameters; rows are returned as []map[string]any. Header memx.rowCount records the count.
insert¶
Body: map[string]any (or JSON object). Keys are sorted, identifiers are double-quoted (after a strict ^[a-zA-Z_][a-zA-Z0-9_.]*$ check), and the statement is INSERT INTO "table" (cols) VALUES ($1, …). Header memx.rowsAffected is set.
vector_search¶
Set memx.vector header to a JSON array of floats. Generated SQL:
SELECT *, MATCH_DENSE("<column>", '[<vec>]') AS score
FROM "<table>" ORDER BY score DESC LIMIT <topK>
text_search¶
Body: the query text (string). Generated SQL:
hybrid_search¶
Set memx.vector header (JSON float array) and the body to the query text. Generated SQL:
SELECT *, FUSION('rrf',
MATCH_DENSE("<vectorColumn>", '[<vec>]'),
MATCH_TEXT("<textColumn>", $1)) AS score
FROM "<table>" ORDER BY score DESC LIMIT <topK>
Consumer¶
When from: memx://...?operation=query is wired, the consumer polls SELECT * FROM "<table>" every pollInterval and dispatches each non-empty result set as a new exchange (body: []map[string]any; headers: memx.rowCount, memx.table).
Headers¶
Read by the producer¶
| Header | Description |
|---|---|
memx.vector |
vector_search / hybrid_search — JSON-encoded float array. |
Written¶
| Header | Description |
|---|---|
memx.rowCount |
Query / search row count. |
memx.rowsAffected |
insert rows affected. |
memx.table |
Consumer — table being polled. |
Examples¶
Hybrid search:
workflows:
- id: search
trigger: { uri: direct://search }
steps:
- set-header:
name: memx.vector
starlang: |
%sl 2.0
output application/json
input payload
---
embed(payload.text)
- target: memx://memx-cluster:5432/kb?table=docs&operation=hybrid_search&topK=10
Polling consumer feeding a Kafka topic:
workflows:
- id: outbox
trigger:
uri: memx://localhost:5432/app?table=outbox_events&pollInterval=5s
steps:
- split:
starlang: payload
- target: kafka://events?bootstrap.servers=kafka:9092
Insert vector + metadata:
- set-body:
starlang: |
%sl 2.0
output application/json
input payload
---
{ "id": payload.id, "content": payload.text, "embedding": payload.vector }
- target: memx://localhost:5432/kb?table=docs&operation=insert
Behavior notes¶
- Identifier safety — table and column names are matched against
^[a-zA-Z_][a-zA-Z0-9_.]*$before being double-quoted into SQL. Anything else is rejected; no injection through table/column params. - simple_protocol exec mode — appended to the DSN so the memx-specific syntax (
MATCH_DENSE([...])) round-trips without prepared-statement rewriting. - Vector literal format —
vectorToStringemits[0.1,0.2,...]— bracketed comma-separated floats with'f', -1, 64formatting. - Pool lifecycle — one
pgxpool.Poolper producer or consumer; closed onStop.
Source¶
pkg/component/memx/memx.go