Apache Pinot

The Pinot connector (CONNECTOR_TYPE=pinot or CONNECTION_TYPE=pinot) translates GQL queries into Pinot SQL and executes them through the Pinot broker SQL API. It uses the shared relational mapping file and is currently read-oriented: MATCH/RETURN queries are supported, while GQL mutations are rejected by the executor.

Translated graph patterns use SQL joins, so MemGQL sends PINOT_QUERY_OPTIONS=useMultistageEngine=true by default.

1. Start Pinot

docker network create memgql-net
 
docker run -d --rm \
    --name pinot-zookeeper-dev \
    --network memgql-net \
    -p 2182:2181 \
    zookeeper:3.9.2
 
docker run -d --rm \
    --name pinot-controller-dev \
    --network memgql-net \
    -p 9010:9000 \
    apachepinot/pinot:latest StartController \
    -zkAddress pinot-zookeeper-dev:2181
 
docker run -d --rm \
    --name pinot-broker-dev \
    --network memgql-net \
    -p 8099:8099 \
    apachepinot/pinot:latest StartBroker \
    -zkAddress pinot-zookeeper-dev:2181
 
docker run -d --rm \
    --name pinot-server-dev \
    --network memgql-net \
    -p 8098:8098 \
    apachepinot/pinot:latest StartServer \
    -zkAddress pinot-zookeeper-dev:2181

2. Seed data

The repository includes a seed script that creates Pinot offline tables and pushes segments matching the default Person/Company mapping.

./rust/tests/pinot/seed.sh

3. Start MemGQL

docker run --rm \
    --name memgql \
    --network memgql-net \
    --stop-timeout 2 \
    -p 7688:7688 \
    --env CONNECTION_TYPE=pinot \
    --env PINOT_URL=http://pinot-broker-dev:8099 \
    --env PINOT_QUERY_OPTIONS=useMultistageEngine=true \
    --env MAPPING_FILE=/data/mapping.json \
    -v ./mapping.json:/data/mapping.json \
    memgraph/memgql:latest

4. Connect

mgconsole --port 7688

5. Query

MATCH (p:Person) RETURN p.name, p.age;
MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name;
MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name;

For environment variables, see Reference.

Supported GQL features

FeaturePinot
MATCH / WHERE / RETURN✓
Pattern-level WHERE (MATCH (n WHERE …))✓
Multiple MATCH clauses in one query✓
OPTIONAL MATCH✓
WITH clause (chain query steps)✓
WITH DISTINCT / WITH … ORDER BY … LIMIT N✓
Multiple chained WITH steps✓
Pass a whole node through WITH n✓
Typed edge (a)-[r:R]->(b)✓
Untyped edge ()-[]->(b)✗
UNION / UNION ALL / UNION DISTINCT✓
INTERSECT / EXCEPT✓
EXISTS { … } / pattern predicates✓
CALL { … } subquery✗
Quantified path (){m,n} / *m..n (bounded)✗
Whole-node RETURN n / whole-rel RETURN r✓
Map projections RETURN n {.a, .b}✗
IN list membership WHERE x IN [...]✓
STARTS WITH / ENDS WITH / CONTAINS✓
collect() aggregate✗
count, sum, avg, min, max✓
COUNT(DISTINCT …)✓
Arithmetic + - * / %✓
CASE WHEN … THEN … ELSE … END✓
COALESCE, NULLIF✓
CAST(x AS STRING | INT | FLOAT | BOOLEAN)✓
Scalar functions (upper, abs, char_length, …)✓
Cypher functions (toUpper, substring, toInteger, …)✓
Query parameters ($x)✓
date('YYYY-MM-DD') returns a Date✗
FOR x IN [...] / UNWIND✗
INSERT (a {…}), incl. an edge between matched nodes✗
INSERT (a {…}) RETURN a.x✗
DELETE✗
SET / REMOVE (property update / delete)✗
DETACH DELETE✗
Quantified path (){m,} (unbounded)✗
Shortest-path (ALL SHORTEST / SHORTEST k)✗