HiI have a very basic Graph requirement , as show in attached example image.I have few questions here:
- is Neo4J not an over kill for this purpose? as I have nodes less that 3000.
- do Neo4J supports finding short test path between two given nodes while specifying criteria for a property of relationship to be met. if yes can someone give a java example for this.
Would be great help if some one can illustrate a a small java class for attached graph as an example.Thanks in advance.Rehan
HiI have a very basic Graph requirement , as show in attached example image.I have few questions here:
- is Neo4J not an over kill for this purpose? as I have nodes less that 3000.
- do Neo4J supports finding short test path between two given nodes while specifying criteria for a property of relationship to be met. if yes can someone give a java example for this.
Would be great help if some one can illustrate a a small java class for attached graph as an example.Thanks in advance.Rehan
--
--
PathFinder<Path> finder = GraphAlgoFactory.allPaths(Traversal.expanderForTypes(relType.CONNECTED, Direction.BOTH),100);
Iterable<Path> paths = finder.findAllPaths(A, M);
Iterator<Path> pIterator = paths.iterator();
while (pIterator.hasNext()){
Path path = pIterator.next();
System.out.println(Traversal.simplePathToString(path));
}import java.util.Iterator;
import org.neo4j.cypher.ExecutionEngine;
import org.neo4j.cypher.ExecutionResult;
import org.neo4j.graphalgo.GraphAlgoFactory;
import org.neo4j.graphalgo.PathFinder;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.PathExpander;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.traversal.Evaluation;
import org.neo4j.graphdb.traversal.Evaluator;
import org.neo4j.graphdb.traversal.Evaluators;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.kernel.Traversal;
import org.testng.annotations.Test;
public class GaphGeneratorImplTest {
private Index<Node> indexService;
private GraphDatabaseService graphDB ;
public enum relType implements RelationshipType
{
CONNECTED
}
@Test
public void f() {
initializeGraphDB();
}
//GraphDatabase Object Initializer
private GraphDatabaseService getUniqueGraphDB(){
if (graphDB==null){
GraphDB gDB = new GraphDB();
graphDB = gDB.getGraphDB();
indexService = graphDB.index().forNodes("name");
}
return graphDB;
}
//Initialize Graph Class
public Boolean initializeGraphDB() {
if (graphDB==null){
getUniqueGraphDB();
}
Transaction tx = graphDB.beginTx();
try {
Node A = getOrCreateNode("A");
Node B = getOrCreateNode("B");
Node C = getOrCreateNode("C");
Node D = getOrCreateNode("D");
Node E = getOrCreateNode("E");
Node F = getOrCreateNode("F");
Node G = getOrCreateNode("G");
Node H = getOrCreateNode("H");
Node I = getOrCreateNode("I");
Node J = getOrCreateNode("J");
Node K = getOrCreateNode("K");
Node L = getOrCreateNode("L");
Node M = getOrCreateNode("M");
System.out.println("Nodes Created");
getOrCreateRelationShip(A, B, (long) 400);
getOrCreateRelationShip(A, C, (long) 200);
getOrCreateRelationShip(B, M, (long) 10);
getOrCreateRelationShip(C, D, (long) 1000);
getOrCreateRelationShip(C, E, (long) 1000);
getOrCreateRelationShip(C, F, (long) 300);
getOrCreateRelationShip(D, I, (long) 1000);
getOrCreateRelationShip(E, H, (long) 1000);
getOrCreateRelationShip(E, G, (long) 500);
getOrCreateRelationShip(F, G, (long) 500);
getOrCreateRelationShip(G, J, (long) 1000);
getOrCreateRelationShip(H, J, (long) 0);
getOrCreateRelationShip(I, L, (long) 500);
getOrCreateRelationShip(J, K, (long) 200);
getOrCreateRelationShip(J, M, (long) 1000);
getOrCreateRelationShip(K, L, (long) 500);
getOrCreateRelationShip(L, M, (long) 800);
tx.success();
long aID = A.getId();
long mID = M.getId();
/*
Evaluator e = new Evaluator() {
@Override
public Evaluation evaluate(Path arg0) {
if(Long.valueOf(arg0.endNode().getSingleRelationship(relType.CONNECTED, Direction.BOTH).getProperty("value").toString())>=200){
return Evaluation.INCLUDE_AND_CONTINUE;
}else{
return Evaluation.EXCLUDE_AND_CONTINUE;
}
}
};
TraversalDescription td = Traversal.description()
.breadthFirst()
.relationships(relType.CONNECTED)
.evaluator( Evaluators.excludeStartPosition()).evaluator(Evaluators.atDepth(1)).evaluator(e);
PathFinder<Path> finder = GraphAlgoFactory.allSimplePaths(Traversal.expanderForTypes(relType.CONNECTED, Direction.BOTH),100);
Iterable<Path> paths = finder.findAllPaths(A, M);
Iterator<Path> pIterator = paths.iterator();
while (pIterator.hasNext()){
Path path = pIterator.next();
System.out.println(Traversal.simplePathToString(path));
}
*/
ExecutionEngine exEngine = new ExecutionEngine(graphDB);
ExecutionResult eReuslt = exEngine.execute("START n=node("+aID+"), m=node("+mID+") MATCH p=allShortestPaths(n-[*]-m) WHERE ALL(r in RELS(p) WHERE r.value >= 200) RETURN p");
//ExecutionResult eReuslt = exEngine.execute("start n=node("+aID+"),m=node("+mID+") match p=allShortestPaths(n-[*]-m) return p ");
System.out.println(eReuslt);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
tx.finish();
graphDB.shutdown();
}
return true;
}
/* Get or Create Node
* Return Node if already exists
* Else create a New node
*
* */
private Node getOrCreateNode( String neName){
if (graphDB==null)
getUniqueGraphDB();
Node node = indexService.get( "name", neName).getSingle();
if ( node == null ){
System.out.println("Creating Node: "+neName);
node = graphDB.createNode();
node.setProperty("name", neName);
indexService.add( node, "name", node);
}
return node;
}
/* Get or Create Relationship
* Return Relationship if already exists
* Else create a New Relationship
*
* */
private Relationship getOrCreateRelationShip(Node sourceNode, Node targetNode, Long value){
if (graphDB==null){
getUniqueGraphDB();
}
// Check if Already Connected
Relationship rel = isRelated(sourceNode, targetNode, relType.CONNECTED);
//if (rel!=null){
Relationship relationship = sourceNode.createRelationshipTo(targetNode, relType.CONNECTED);
System.out.println("Created Relationship between :"+sourceNode.getProperty("name")+" to "+targetNode.getProperty("name"));
relationship.setProperty("value", value);
return relationship;
//}
//return rel;
}
/* Check if Relationship Exists
* Return Relationship if already exists
* */
private Relationship isRelated(Node a, Node b, RelationshipType type) {
if (a.hasRelationship()){
Iterable<Relationship> rels = a.getRelationships();
if (rels!=null){
for(Relationship r : rels) {
if (r.getType().equals(type)){
if (r.getStartNode() == b || r.getEndNode()==b){
return r;
}
}
}
}
}
return null;
}
}
Creating Node: A
Creating Node: B
Creating Node: C
Creating Node: D
Creating Node: E
Creating Node: F
Creating Node: G
Creating Node: H
Creating Node: I
Creating Node: J
Creating Node: K
Creating Node: L
Creating Node: M
Nodes Created
Created Relationship between :A to B
Created Relationship between :A to C
Created Relationship between :B to M
Created Relationship between :C to D
Created Relationship between :C to E
Created Relationship between :C to F
Created Relationship between :D to I
Created Relationship between :E to H
Created Relationship between :E to G
Created Relationship between :F to G
Created Relationship between :G to J
Created Relationship between :H to J
Created Relationship between :I to L
Created Relationship between :J to K
Created Relationship between :J to M
Created Relationship between :K to L
Created Relationship between :L to M
empty iterator
PASSED: fgraphDB = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(DB_PATH).
setConfig( GraphDatabaseSettings.relationship_keys_indexable, "value" ).
setConfig( GraphDatabaseSettings.node_auto_indexing, true).
setConfig( GraphDatabaseSettings.relationship_auto_indexing, true).
newGraphDatabase();graphDB = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(DB_PATH).
setConfig( GraphDatabaseSettings.relationship_keys_indexable, "value" ).
setConfig( GraphDatabaseSettings.node_auto_indexing, "true").
setConfig( GraphDatabaseSettings.relationship_auto_indexing, "true").
newGraphDatabase();--
--
START a=node:node_auto_index(name="A"), m=node:node_auto_index(name="M")MATCH p=a-[*]-mWHERE ALL(r in RELS(p) WHERE r.value >= 200)
orWITH MIN(LENGTH(p)) AS l, collect(p) as pathsRETURN filter(p in paths : length(p) = l)
RETURN head(filter(p in paths : length(p) = l))
--
Relationship Already Exists
+-------------------------------------------------------------------------------------------------------------+
| p |
+-------------------------------------------------------------------------------------------------------------+
| [Node[1]{name:"A"},:CONNECTED[0] {value:400},Node[2]{name:"B"},:CONNECTED[2] {value:10},Node[13]{name:"M"}] |
+-------------------------------------------------------------------------------------------------------------+
1 row
125 ms--
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| p |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| [Node[1]{name:"A"},:CONNECTED[1] {value:200},Node[3]{name:"C"},:CONNECTED[3] {value:1000},Node[4]{name:"D"},:CONNECTED[6] {value:1000},Node[9]{name:"I"},:CONNECTED[12] {value:500},Node[12]{name:"L"},:CONNECTED[16] {value:800},Node[13]{name:"M"}] |
| [Node[1]{name:"A"},:CONNECTED[1] {value:200},Node[3]{name:"C"},:CONNECTED[4] {value:1000},Node[5]{name:"E"},:CONNECTED[8] {value:500},Node[7]{name:"G"},:CONNECTED[10] {value:1000},Node[10]{name:"J"},:CONNECTED[14] {value:1000},Node[13]{name:"M"}] |
| [Node[1]{name:"A"},:CONNECTED[1] {value:200},Node[3]{name:"C"},:CONNECTED[5] {value:300},Node[6]{name:"F"},:CONNECTED[9] {value:500},Node[7]{name:"G"},:CONNECTED[10] {value:1000},Node[10]{name:"J"},:CONNECTED[14] {value:1000},Node[13]{name:"M"}] |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3 rows
297 msSTART a=node:node_auto_index(name="A"), m=node:node_auto_index(name="M")MATCH p=a-[*]-mWHERE ALL(r in RELS(p) WHERE r.value >= 200)
RETURN p
ORDER BY length(p) desc limit 5
--
--
START a=node:node_auto_index(name="A") , m=node:node_auto_index(name="M") MATCH p=a-[*]-m WHERE ALL(r in RELS(p) WHERE r.value >= 200) RETURN p ORDER BY length(p) desc limit 5START a=node:node_auto_index(name="B") , m=node:node_auto_index(name="M") MATCH p=b-[*]-m, a-[:CONNECTED]-b WHERE ALL(r in RELS(p) WHERE r.value >= 200) RETURN p ORDER BY length(p) desc limit 5