Example Cypher usage
Occasionally it's useful to use Cypher to munge the graph. Here is an example of that. The situation was as follows:
a group was added for annotation/link moderation (with id "moderators")
this group would be given access to private notes if their creator marked them promotable
however, there were existing promotable annotations already created that did not grant access to the moderators group (rather, they weren't accessible to anyone except admins)
So what we needed to do was:
find the moderators group
find all the promotable notes (with attribute
isPromotable
)check there's not already an access relation from annotation to the moderators group (with the label
access
from item to user/group)
Then finally:
create the access relationship on these annotations
Here's some Cypher to do the query part and check we're getting what we expect (a few annotations):
MATCH (n:Annotation {isPromotable: true}), (mods: Group {__id:"moderators"})
WHERE NOT (n)-[:access]->(mods)
RETURN n, n.body
Once happy that we're getting all the annotations that need fixing we can modify our query to create the relationship:
MATCH (n:Annotation {isPromotable: true}), (mods: Group {__id:"moderators"})
WHERE NOT (n)-[:access]->(mods)
CREATE (n)-[:access]->(mods)
RETURN n, n.body
To briefly run through this:
MATCH (n:Annotation {isPromotable: true}), (mods: Group {__id:"moderators"})``
Locates annotations which are promotable, and the moderators group, the latter
using its global __id
property
WHERE NOT (n)-[:access]->(mods)
Restricts the found nodes to those which
don't already have an access
relationship between the note and the
moderators group
CREATE n-[:access]->mods
Create the access relationship, not caring about the result
RETURN n, n.body
Return something pretty arbitrary (the node and its body). Had we bound the new relationship to a name in the previous step we could have returned that instead
Example 2: Locating "orphan" documentary units
It's a quirk of the database that documentary unit items can be
"orphaned" of someone deletes their repository or parent item, since
this does not trigger a delete cascade (for safety purposes). These
orphans can be located by finding documentary unit items with neither
a heldBy
or a childOf
relationship, like so:
MATCH (d:DocumentaryUnit)
WHERE NOT (d)-[:heldBy]-() AND NOT (d)-[:childOf]->()
RETURN d.__id