The easiest way to run Neo4j is by using the official docker image:
$ docker run -p 7474:7474 -p 7687:7687 neo4j:3.4
Neo4j supports a powerful query and a create, read, update, and delete (CRUD) language called Cypher (https://neo4j.com/docs/developer-manual/3.4/cypher/), and it also supports the REST API interface and Java, Python, C#, and JavaScript drivers to work with Cypher.
When service is up and running, we can access the Neo4j UI; we can open the browser at: http://localhost:7474/browser/.
The following screenshot shows the user interface of the Neo4j UI:
Neo4j will ask to change the password before you proceed; the default username is neo4j and the password is neo4j.
Now we can build our asset model with Cypher:
- Create the asset. On the Neo4j user interface, we can write the following commands:
CREATE (CT001:Pump {name:'CT001', alias:'Pump-SN-993416776', model:'standard'})
CREATE (Train1:Section {name:'Production Train 1'})
CREATE (SydneyPlant:Plant {name:'Plant of ACME in Sydney'})
CREATE (ACME:Company {name:'ACME International'})
The syntax is very simple:
CREATE
ASSETNAME:TYPE {ATTRIBUTES}
- Create the relationship among the assets:
CREATE
(CT001)-[:BELONGING_OF {roles:['Part of']}]->(Train1),
(Train1)-[:BELONGING_OF {roles:['Part of']}]->(SydneyPlant),
(SydneyPlant)-[:BELONGING_OF {roles:['Managed by']}]->(ACME)
The syntax is also very intuitive here:
CREATE
ASSETNAME –[RELATIONSHIP]-> ASSETNAME
- Create the measures (tags) and associate them to the CT001:Pump asset:
CREATE (TEMP01:Measure {name:'CT001.TEMPERATURE01', alias:'TEMP01', type:'TEMPERATURE', uom:'DEG'})
CREATE (FLOW01:Measure {name:'CT001.FLOW01', alias:'FLOW01', type:'FLOW', uom:'sm3/sec'})
CREATE
(TEMP01)-[:MEASURE_OF]->(CT001),
(FLOW01)-[:MEASURE_OF]->(CT001)
If everything went well, we can ask for the temperatures of the assets belonging to the section Train1, as follows:
MATCH (:Section)<-[:BELONGING_OF]-(EQ)<-[:MEASURE_OF]-(M)
WHERE M.type='TEMPERATURE'
RETURN EQ.name, M.name, M.uom
The result of this is as follows:
Neo4j has a very flexible language, and we can work with Cypher using Python, JavaScript, C#, or the Java driver. To work with JavaScript, we need to install the driver:
$ mkdir neo4j
$ cd neo4j
$ npm init
$ npm install neo4j-driver
We are now ready to develop our code. Build the ask_for_measure.js file with the following code:
const neo4j = require('neo4j-driver/lib/index.js').v1;
const driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "admin"));
const session = driver.session();
const resultPromise = session.run(
"MATCH (:Section)<-[:BELONGING_OF]-(EQ)<-[:MEASURE_OF]-(M) WHERE M.type='TEMPERATURE' RETURN EQ.name, M.name, M.uom")
.then(result => {
session.close();
const singleRecord = result.records[0];
const measure = singleRecord.get(0);
console.log(singleRecord);
// on application exit:
driver.close();
});
We can then simply run the following command:
$ node ask_for_measure.js
This will give us the following result:
Record {
keys: [ 'EQ.name', 'M.name', 'M.uom' ],
length: 3,
_fields: [ 'CT001', 'CT001.TEMPERATURE01', 'DEG' ],
_fieldLookup: { 'EQ.name': 0, 'M.name': 1, 'M.uom': 2 } }
The following screenshot shows the complete log: