Data integration where you just say what you want. Your data lives in different systems — SPOQE lets you query them as one.
Write the shape of the result you need. SPOQE compiles it to native queries, crosses the boundaries, and hands it back — in exactly the shape you asked for.
Your query describes what the result looks like. SPOQE finds data that fits.
;; Pull tracks, titles, reviews, and notes {:pull [(tracks-by "Miles Davis") :dc/title {:dc/creator [:foaf/name]} {:review/has [:review/stars :review/text]} {:notes/has (text-match "modal")}]}
Write the shape of the data you want. Nested maps describe traversals. The query IS the result schema.
SPOQE compiles your shape into native queries — SPARQL for the triplestore, SQL for Postgres. Bridges connect the sources.
Results come back in the exact shape you described. One query, multiple sources, one result. No joins to write.
SPOQE compiles your query into native instructions for each backend.
{:pull
[(tracks-by "Miles Davis")
:dc/title ; triplestore
{:dc/creator [:foaf/name]} ; triplestore
{:review/has ; Postgres
[:review/stars
:review/text]}
{:notes/has ; Elasticsearch
(text-match "modal")}]}
SELECT ?track ?title ?name
WHERE {
?track dc:creator ?artist .
?artist foaf:name "Miles Davis" .
?track dc:title ?title .
?artist foaf:name ?name .
}
IRI → track_id
SELECT stars, text FROM reviews WHERE track_id IN (42, 87)
IRI → track_id
{"query": {"bool": {"must": [
{"terms": {"track_id": [42, 87]}},
{"match": {"notes": "modal"}}
]}}}
[{:dc/title "Blue in Green"
:dc/creator {:foaf/name "Miles Davis"}
:review/has [{:review/stars 5 :review/text "Haunting"}]
:notes/has [{:notes/text "...pioneering modal interchange..."}]}
{:dc/title "So What"
:dc/creator {:foaf/name "Miles Davis"}
:review/has [{:review/stars 4 :review/text "Classic"}]
:notes/has [{:notes/text "...modal jazz at its purest..."}]}]
No hidden magic. No string templates. The query describes the shape. The system fills it. You see everything.