How to form a graph DB from relation object

I wrote a python code which will extract meaningful relation from a given text as an input.

Please check the below image for better understanding

Jupyter123_0-1671519287785.png

The above image show that, I extracted the relation from the text

Now i want to move those relation object to neo4j and form a graph?

how do i do that? what is the query for that?

hi @Estelle , thanks for the response.

Well, Instead of converting the object to JSON

Is it possible to do this via python object?

Pls note that: I already connected python code and neo4j by this command:

from neo4j import GraphDatabase

data_base_connection1 = GraphDatabase.driver(uri = "bolt://localhost:7687", auth=("neo4j", "password"))
session1 = data_base_connection1.session()

In my python program i have a class called KB and inside that class i have a method called def print(self): and some logic inside that..

So whenever i type KB.print()

i get relation object [ the one that i shown in above image]

so what would be the query to send that relation object from python to neo4j and form a graph?

Hello,

You can save your result as JSON and import it with APOC: apoc.load.json (https://neo4j.com/labs/apoc/4.4/overview/apoc.load/apoc.load.json/)

Not tested, but query could look like this:

CALL apoc.load.json("path/to/file.json") YIELD value
MERGE (head:Entity {name: value.head})
MERGE (tail:Entity {name: value.tail})
CALL apoc.create.relationship(head, value.type, value.meta, tail) YIELD rel
RETURN count(rel)

Explantions:

  • "get or create" the head entity whose name is the head value is the JSON
  • Same for the tail entity
    NOTE: if entities are already in the database, just use MATCH instead of MERGE
  • Then, create the relationship between entities, using apoc.create.relationship to create a relationship with dynamic type (https://neo4j.com/labs/apoc/4.4/overview/apoc.create/apoc.create.relationship/)
  • In the end, just return the number of created relationships. Up to you to decide what you want to see in the end, if you want to see something

Sure you can also do that. In your KB class you can probably have a method returning dictionnaries, then the dict keys are used as variables in the query you execute with the driver, something like:

query = """
MERGE (head:Entity {name: $head})
MERGE (tail:Entity {name: $tail})
CALL apoc.create.relationship(head, $type, $meta, tail) YIELD rel
RETURN count(rel)
"""
params = {
   "head": "",
   "type": "",
   "tail": "",
   "meta": {}
}
with driver.session() as s:
   s.run(query, params)

Jupyter123_0-1671534233599.png

@Estelle Hi, im getting this error.

@glilienfield i saw your graph, it's close to my expected output.
just one quick change, instead of displaying node as numbers, can you display as corresponding to head and tail name in json?

something like this

Jupyter123_0-1671637337614.png

The json file consists of a single json object with key 'relations', whose value is an array. As such, @Estelle query need to be modified to account for that. Try the following:

CALL apoc.load.json("file:///sample.json") YIELD value
UNWIND value.relations as relation
MERGE (head:Entity {name: relation.head})
MERGE (tail:Entity {name: relation.tail})
WITH head, relation, tail, toUpper(replace(relation.type, " ", "_")) as type
CALL apoc.create.relationship(head, type, {}, tail) YIELD rel
RETURN count(rel)

I replaced the relationship values to conform to best practices. Also, the 'meta' value is a json map, which can not be saved as a relationship property. Is there data in 'meta' that you want to save?

hi there @glilienfield @Estelle
i dont want the meta value

i just want the 'head' node, 'tail' node and 'type' relation and that should form a graph.

by the way, i executed your code and i get like this.
please see below image

Jupyter123_0-1671636647305.png

still i haven't got any graph though.

Interesting. I got 23 relationships. What does the output look like when you execute:

CALL apoc.load.json("file:///sample.json") YIELD value
return value

You did not attach your image. This is what I got:

Screen Shot 2022-12-21 at 10.33.51 AM.png

Its because you have an extra 'with' clause at the end of the first line. You need to put the 'with' between the 'merge' and 'call' on line 3.

WITH head, value, tail

@Estelle hi there, the query seems to be showing many errors like...

in-between merge and call 'with' should come.

could you please test the query and let me know

@glilienfield the output look like this

Jupyter123_0-1671637863033.png

i dont see any nodes getting created

i edited it, pls check the image and it's nice you have got my expected graph.

Could you check what's the error i did tho?

Hi @Jupyter123 ,

The error message seems quite explicit, what have you tried to fix the query and what is your problem?

Ok, that structure is different from what you posted. That data looks to be an array. It is not a value of the 'relation' key, as was in the file you posted. That would explain the issue. Can you post the final json file? I can modify the query.

hey @Estelle

I have uploaded JSON file in the below link. Please have a look

https://easyupload.io/y7ne07

I want that JSON data to be displayed in neo4j graph DB with nodes and edges

What is the query for that?

Could you try to test that JSON file in neo4j and let me know if it's displaying in neo4j as graph?

I want the result to be like this

Jupyter123_0-1671619816743.png

@glilienfield

hey mate, its working now

my bad , earlier i had wrong JSON file.

Now i updated json and it works.

Jupyter123_0-1671681774130.png

thank you very much

hi @glilienfield , morning.

oh yeah i just checked, i used different wrong json structure.

let me use the one which i sent you and will update you

hey @glilienfield

just a small help

can you modify the same query in such a way where there should be a top node among all these nodes and that top node should connect every head node.

top node should be named as 'main' and that 'main' top node should relate with every other head node .

pls note that: top node is not in json file.

json file has head node, tail node and type(relation)

i want to create a single top node and that top node should match all head nodes..

what's the query for that?

something like this

Jupyter123_0-1672050735285.png