0
votes

I am trying to create a graph that stores time based iterations between nodes. I would like the nodes to be unique and relationships between nodes to be unique given the timestamp property.

My first attempt creates 2 nodes and 1 relationship which is not what I want.

from py2neo import neo4j, node, rel

graph_db = neo4j.GraphDatabaseService()
graph_db.get_or_create_index(neo4j.Node, "node_index")

batch = neo4j.WriteBatch(graph_db)

# a TALKED_TO b at timestamp 0 
batch.get_or_create_indexed_node('node_index', 'name', 'a', {'name': 'a'})
batch.get_or_create_indexed_node('node_index', 'name', 'b', {'name': 'b'})
batch.get_or_create_indexed_relationship('rel_index', 'type', 'TALKED_TO', 0, 'TALKED_TO', 1, {"timestamp": 0})

# a TALKED_TO b at timestamp 1
batch.get_or_create_indexed_node('node_index', 'name', 'a', {'name': 'a'})
batch.get_or_create_indexed_node('node_index', 'name', 'b', {'name': 'b'})
batch.get_or_create_indexed_relationship('rel_index', 'type', 'TALKED_TO', 3, 'TALKED_TO', 4, {"timestamp": 1})

# a TALKED_TO b at timestamp 2
batch.get_or_create_indexed_node('node_index', 'name', 'a', {'name': 'a'})
batch.get_or_create_indexed_node('node_index', 'name', 'b', {'name': 'b'})
batch.get_or_create_indexed_relationship('rel_index', 'type', 'TALKED_TO', 6, 'TALKED_TO', 7, {"timestamp": 0})

results = batch.submit()
print results

#[Node('http://localhost:7474/db/data/node/2'), 
#Node('http://localhost:7474/db/data/node/3'), 
#Relationship('http://localhost:7474/db/data/relationship/0'), 
#Node('http://localhost:7474/db/data/node/2'), 
#Node('http://localhost:7474/db/data/node/3'), 
#Relationship('http://localhost:7474/db/data/relationship/0'), 
#Node('http://localhost:7474/db/data/node/2'), 
#Node('http://localhost:7474/db/data/node/3'),     
#Relationship('http://localhost:7474/db/data/relationship/0')]

My second attempt creates 2 nodes and 0 relations, not sure why it fails to create any relationships.

from py2neo import neo4j, node, rel

graph_db = neo4j.GraphDatabaseService()
graph_db.get_or_create_index(neo4j.Node, "node_index")

batch = neo4j.WriteBatch(graph_db)

# a TALKED_TO b at timestamp 0 
batch.get_or_create_indexed_node('node_index', 'name', 'a', {'name': 'a'})
batch.get_or_create_indexed_node('node_index', 'name', 'b', {'name': 'b'})
batch.create(rel(0, 'TALKED_TO', 1, {"timestamp": 0}))

# a TALKED_TO b at timestamp 1
batch.get_or_create_indexed_node('node_index', 'name', 'a', {'name': 'a'})
batch.get_or_create_indexed_node('node_index', 'name', 'b', {'name': 'b'})
batch.create(rel(3, 'TALKED_TO', 4, {"timestamp": 1}))

# a TALKED_TO b at timestamp 2
batch.get_or_create_indexed_node('node_index', 'name', 'a', {'name': 'a'})
batch.get_or_create_indexed_node('node_index', 'name', 'b', {'name': 'b'})
batch.create(rel(6, 'TALKED_TO', 7, {"timestamp": 0}))

results = batch.submit()
print results

#[Node('http://localhost:7474/db/data/node/2'), 
#Node('http://localhost:7474/db/data/node/3'), 
#None]

So how do I achieve what is depicted in the image below?

enter image description here

1

1 Answers

0
votes

Okay so I think I figured it out but I'm not sure if its efficient. Does anyone know a better way than the following?

# Create nodes a and b if they do not exist.
query = """MERGE (p:Person { name: {name} }) RETURN p"""
cypher_query = neo4j.CypherQuery(neo4j_graph, query )
result = cypher_query .execute(name='a')
result = cypher_query .execute(name='b')

# Create a relationship between a and b if it does not exist with the given timestamp value.
query = """
    MATCH (a:Person {name: {a}}), (b:Person {name: {b}})
    MERGE (a)-[r:TALKED_TO {timestamp: {timestamp}}]->(b)
    RETURN r
"""
cypher_query = neo4j.CypherQuery(neo4j_graph, query)
result = cypher_query.execute(a='a', b='b', timestamp=0)
result = cypher_query.execute(a='a', b='b', timestamp=1)