Standing queries are defined with graph patterns. For the sake of convenience, we also provide an API option where you define the pattern you want to find using a Cypher query. For instance, suppose we want to match a pattern of a person and their two parents:
curl -X POST "http://localhost:8080/api/v1/query/standing/my_sq" \
-H "accept: */*" \
-H "Content-Type: application/json" \
-d '{
"name": "my_sq",
"pattern": {
"type": "Cypher",
"query": "MATCH ({ gender: \"female\" })<-[:has_parent]-(n)-[:has_parent]->({ gender: \"male\" }) return n"
},
"output": {
"type": "CypherQuery",
"parameter": "props",
"query": "MATCH (n) WHERE id(n) = $props.id SET n.has_parents = $props.isPositiveMatch",
"parallelism": 1
},
"type": "Universal"
}'
The "output" part of that is where we define the possible sorts of things we want to be able to do. In this example, we just set a property on the node that matched. We have options to
- POST results to a URL
- stream results to Kafka/Kinesis/Files
- Listen to results over websockets
- ...
See "Standing queries" section of the REST API docs for more ways to specify graph patterns, or actions to take using the outputs of those matches.
For long-running production use cases (where there is just a continuous flow of data), we have an ingest API that lets you hook into Kafka/Kinesis (see "Ingest streams" section of the REST API docs page)
For experiments and exploration, we support simpler ingest directly through Cypher queries of JSON or CSV that are accessible. For example:
- https://gist.githubusercontent.com/harpocrates/b3d5774c55e730fa89b81477a9d38bb5/raw/83b91249843bdcf0ce0ecbcf03e62e64158cff4a/harry_potter.json.log
- https://gist.githubusercontent.com/harpocrates/5564ff07dc6ff364f2167a960a2dfd00/raw/62602d648e0915d53fff6f1f41540e29e037b00b/harry_potter.csv
Here's a sample query that ingests a small graph of parents and children in Harry Potter
(this text can be copy-pasted straight into the UI, although it looks nicer in cypher-shell
)
CALL loadJsonLines("https://gist.githubusercontent.com/harpocrates/b3d5774c55e730fa89b81477a9d38bb5/raw/83b91249843bdcf0ce0ecbcf03e62e64158cff4a/harry_potter.json.log") YIELD record AS record
MATCH (p) WHERE id(p) = hash(record.name)
SET p = { name: record.name, gender: record.gender, birth_year: record.birth_year }
SET p: Person
WITH record.children AS childrenNames, p
UNWIND childrenNames AS childName
MATCH (c) WHERE id(c) = hash(childName)
CREATE (c)-[:has_parent]->(p)
Note how after ingest, our standing queries have automatically set the has_parents
property on
nodes to reflect whether they have two parents in the graph ("Ron" does, but "Arthur" doesn't)