![](/style/images/good.png)
![](/style/images/bad.png)
Bruggen Blog: Contact tracing in Neo4j: using triggers to automate actions
source link: http://blog.bruggen.com/2021/03/contact-tracing-in-neo4j-using-triggers.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Monday, 8 March 2021
Contact tracing in Neo4j: using triggers to automate actions
What’s a Trigger?If you haven’t worked with triggers before, a trigger is a database method of running some action whenever an event happens. You can use them to make the database react to events, rather than passively accept data, which makes them a good fit for streaming data, which is a set of events coming in.Triggers need two pieces:
- A trigger condition (which event should the trigger fire on?)
- A trigger action (what to do when the trigger fires?)
Triggers are available in Neo4j through Awesome Procedures on Cypher (APOC), and you can find the documentation on them here.
Installing and preparing
So the first thing we need to do is to create new database in Neo4j Desktop. Once installed, we should install the APOC plugin, which should be directly available in Neo4j Desktop's "plugins" section. The trigger functionality that we will be using us actually part of the APOC library, and you can find documentation on them over here.
In order to generate the dataset, I will use the Faker plugin again. See the previous blogpost for more on that, but installing that is actually really easy. First we need to download the latest release from github, unzip that file into plugins directory of your freshly baked server, and then manually do a small piece of restructuring in the file structure:
- put neo4jFaker-0.9.1.jar in plugins directory
- and put ddgres directory in plugins directory.
- delete all other directories
dbms.security.procedures.unrestricted=fkr.*
to neo4j.conf. Easy. The file structure should look like this:
And the neo4j.conf should have a line like this.Once that's done the last change is to allow the apoc triggers to run by adding
apoc.trigger.enabled=true
Generating the dataset
call dbms.functions() yield namewith namewhere name starts with "fkr"return *
Next we just need to run two queries to create the dataset: 5000 persons with 15000 MEETS relationships.
foreach (i in range(1,5000) |create (p:Person { id : i })set p += fkr.person('1940-01-01','2020-05-15')set p.healthstatus = fkr.stringElement("Sick,Healthy")set p.confirmedtime = datetime()-duration("P"+toInteger(round(rand()*100))+"DT"+toInteger(round(rand()*10))+"H")set p.birthDate = datetime(p.birthDate)set p.addresslocation = point({x: toFloat(51.210197+rand()/100), y: toFloat(4.402771+rand()/100)})set p.name = p.fullNameremove p.fullName
match (p:Person)with collect(p) as personscall fkr.createRelations(persons, "MEETS" , persons, "1-n") yield relationships as meetsRelations1call fkr.createRelations(persons, "MEETS" , persons, "1-n") yield relationships as meetsRelations2call fkr.createRelations(persons, "MEETS" , persons, "1-n") yield relationships as meetsRelations3with meetsRelations1+meetsRelations2+meetsRelations3 as meetsRelationsunwind meetsRelations as meetsRelationset meetsRelation.starttime = datetime()-duration("P"+toInteger(round(rand()*100))+"DT"+toInteger(round(rand()*10))+"H")set meetsRelation.endtime = meetsRelation.starttime + duration("PT"+toInteger(round(rand()*10))+"H"+toInteger(round(rand()*60))+"M")set meetsRelation.meettime = duration.between(meetsRelation.starttime,meetsRelation.endtime)set meetsRelation.meettimeinseconds=meetsRelation.meettime.seconds;
Working with triggers
As mentioned above, you can find the documentation for the trigger procedures and functions over here. Once the configuration flag is set (apoc.trigger.enabled=true) in neo4j.conf, we can add the triggers to the database, and start testing them. so let's add them first.
Adding two triggers
You will find that there are different types of triggers that you can add. I will explore two types in this post:
- a trigger that will fire as soon as a LABEL is added to a node in the database.
- a trigger that will fire as soon as a property is set in the database.
CALL apoc.trigger.add('highriskpersonadded','UNWIND apoc.trigger.nodesByLabel($assignedLabels,"HighRiskPerson") AS n MATCH (n)-[:MEETS]-(p:Person) set p:ElevatedRiskPerson',{phase:'after'}
CALL apoc.trigger.add('healthstatuspropertychangedtosick','UNWIND apoc.trigger.propertiesByKey($assignedNodeProperties,"healthstatus") AS propwith prop.node as nMATCH (n)-[:MEETS]-(p:Person) where n.healthstatus = "Sick"set p:MuchElevatedRiskPerson',{phase:'after'}
Managing the triggers
- Listing the trigger:
call apoc.trigger.list()
- There's another procedure for removing the trigger:
call apoc.trigger.remove('<name of trigger>') - And one for pausing the trigger:
call apoc.trigger.pause('<name of trigger>') - Or resuming the trigger:
call apoc.trigger.resume('<name of trigger>')
Triggering the triggers
match (p:Person {healthstatus:"Healthy"})with plimit 1set p:HighRiskPerson;
So our first trigger is clearly working. Let's try the other one.
match (p:Person {healthstatus:"Healthy"})with plimit 1set p:VeryHighRiskPersonset p.healthstatus = "Sick";
So that all seems to have worked. This really allows for much more automated actions on the database, which could be extremely useful in a sensitive use case like Contact Tracing - but I could equally see how this would be super useful for use cases like Fraud Detection or something similar.
No comments:
Post a comment
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK