package neo4JUtils; import java.io.FileWriter; import java.io.IOException; import java.util.Iterator; import model.TripletRelation; import org.apache.commons.lang.StringEscapeUtils; import org.neo4j.cypher.javacompat.ExecutionEngine; import org.neo4j.graphdb.DynamicLabel; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.factory.GraphDatabaseFactory; import org.neo4j.graphdb.schema.Schema; import org.neo4j.helpers.collection.IteratorUtil; import org.neo4j.tooling.GlobalGraphOperations; public class Neo4JDb { private final static String PROP_NAME = "value"; private final static String PROP_CONFIDENCE = "conf"; private final static String PROP_OCCURRENCES = "occurrences"; private final static String LAB_SUBJECT = "subject"; private final static String LAB_PREDICATE = "predicate"; private final static String LAB_OBJECT = "object"; protected GraphDatabaseService graphDb; private static enum RelTypes implements RelationshipType { RELATES } public Neo4JDb(String dbUrl) { graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(dbUrl); registerShutdownHook(graphDb); } // TODO define relation for pronouns public void insertTriplet(TripletRelation triplet, boolean mergeSubject) { final Label label_sub = DynamicLabel.label(LAB_SUBJECT); final Label label_obj = DynamicLabel.label(LAB_OBJECT); Node arg1 = null; if (mergeSubject) { arg1 = getNode(null, PROP_NAME, triplet.getArg1() .toLowerCase()); } try (Transaction tx = graphDb.beginTx()) { if (arg1 == null) { arg1 = graphDb.createNode(label_sub); arg1.setProperty(PROP_OCCURRENCES, 1); arg1.setProperty(PROP_NAME, triplet.getArg1().toLowerCase()); } else { int occurences = (Integer) arg1.getProperty(PROP_OCCURRENCES) + 1; arg1.setProperty(PROP_OCCURRENCES, occurences); } Node arg2 = graphDb.createNode(label_obj); arg2.setProperty(PROP_OCCURRENCES, 1); arg2.setProperty(PROP_NAME, triplet.getArg2().toLowerCase()); Relationship relationship = arg1.createRelationshipTo(arg2, RelTypes.RELATES); relationship.setProperty(PROP_NAME, triplet.getRelation() .toLowerCase()); //confidence relationship.setProperty(PROP_CONFIDENCE, triplet.getConfidence()); tx.success(); } } // NOTE: here we return a node supposed to be unique by label, key and value // null if the nodeList is empty private Node getNode(Label label, String key, Object value) { Node node = null; try (Transaction tx = graphDb.beginTx()) { ResourceIterator<Node> nodes = null; if (label != null){ nodes = graphDb.findNodesByLabelAndProperty( label, key, value).iterator(); } else { String validValue = StringEscapeUtils.escapeJavaScript((String) value); ExecutionEngine engine = new ExecutionEngine(graphDb); nodes = engine.execute( "START n=node(*)" + " WHERE n." + key + "=\"" + validValue + "\"" + " RETURN n").columnAs("n"); } if (nodes.hasNext()) { node = nodes.next(); } nodes.close(); } return node; } public void createIndexes() { try (Transaction tx = graphDb.beginTx()) { Schema schema = graphDb.schema(); schema.indexFor(DynamicLabel.label(LAB_SUBJECT)) .on(PROP_NAME).create(); tx.success(); } } public GraphDatabaseService getDb() { return graphDb; } public void shutdown() { graphDb.shutdown(); } public void writeOutContent(String filename) { GlobalGraphOperations ops = GlobalGraphOperations.at(graphDb); ExecutionEngine engine = new ExecutionEngine(graphDb); try (FileWriter writer = new FileWriter(filename); Transaction tx = graphDb.beginTx()) { for (Node n : ops.getAllNodes()) { writer.write("[" + n.getId() + "," + n.getProperty(PROP_NAME) + ",["); Iterator<Node> connected = engine.execute( "START s=node(" + n.getId() + ") MATCH s-[r]->n RETURN n").columnAs("n"); for (Node e : IteratorUtil.asIterable(connected)) { Iterator<String> rel = engine.execute( "START s=node(" + n.getId() + "), e=node(" + e.getId() + ") MATCH s-[r]->e RETURN r.value") .columnAs("r.value"); String relVal = rel.hasNext()? rel.next() : ""; writer.write("[" + e.getId() + "," + relVal + "],"); } writer.write("]]\n"); } tx.success(); } catch (IOException e1) { e1.printStackTrace(); } } public TripletRelation getRelation(long id){ TripletRelation t = new TripletRelation(); try (Transaction tx = graphDb.beginTx()) { Relationship rel = graphDb.getRelationshipById(id); t.setArg1(rel.getStartNode().getProperty(PROP_NAME).toString()); t.setRelation(rel.getProperty(PROP_NAME).toString()); t.setArg2(rel.getEndNode().getProperty(PROP_NAME).toString()); t.setConfidence(Double.valueOf(rel.getProperty(PROP_CONFIDENCE).toString())); } return t; } private static void registerShutdownHook(final GraphDatabaseService graphDb) { // Registers a shutdown hook for the Neo4j instance so that it // shuts down nicely when the VM exits (even if you "Ctrl-C" the // running application). Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { graphDb.shutdown(); } }); } }