I am attempting to create the glycolytic pathway shown in the image at the bottom of this question, in Neo4j, using these data:
glycolysis_bioentities.csv
name
α-D-glucose
glucose 6-phosphate
fructose 6-phosphate
"fructose 1,6-bisphosphate"
dihydroxyacetone phosphate
D-glyceraldehyde 3-phosphate
"1,3-bisphosphoglycerate"
3-phosphoglycerate
2-phosphoglycerate
phosphoenolpyruvate
pyruvate
hexokinase
glucose-6-phosphatase
phosphoglucose isomerase
phosphofructokinase
"fructose-bisphosphate aldolase, class I"
triosephosphate isomerase (TIM)
glyceraldehyde-3-phosphate dehydrogenase
phosphoglycerate kinase
phosphoglycerate mutase
enolase
pyruvate kinase
glycolysis_relations.csv
source,relation,target
α-D-glucose,substrate_of,hexokinase
hexokinase,yields,glucose 6-phosphate
glucose 6-phosphate,substrate_of,glucose-6-phosphatase
glucose-6-phosphatase,yields,α-D-glucose
glucose 6-phosphate,substrate_of,phosphoglucose isomerase
phosphoglucose isomerase,yields,fructose 6-phosphate
fructose 6-phosphate,substrate_of,phosphofructokinase
phosphofructokinase,yields,"fructose 1,6-bisphosphate"
"fructose 1,6-bisphosphate",substrate_of,"fructose-bisphosphate aldolase, class I"
"fructose-bisphosphate aldolase, class I",yields,D-glyceraldehyde 3-phosphate
D-glyceraldehyde 3-phosphate,substrate_of,glyceraldehyde-3-phosphate dehydrogenase
D-glyceraldehyde 3-phosphate,substrate_of,triosephosphate isomerase (TIM)
triosephosphate isomerase (TIM),yields,dihydroxyacetone phosphate
glyceraldehyde-3-phosphate dehydrogenase,yields,"1,3-bisphosphoglycerate"
"1,3-bisphosphoglycerate",substrate_of,phosphoglycerate kinase
phosphoglycerate kinase,yields,3-phosphoglycerate
3-phosphoglycerate,substrate_of,phosphoglycerate mutase
phosphoglycerate mutase,yields,2-phosphoglycerate
2-phosphoglycerate,substrate_of,enolase
enolase,yields,phosphoenolpyruvate
phosphoenolpyruvate,substrate_of,pyruvate kinase
pyruvate kinase,yields,pyruvate
This is what I have, thus far,
... using this cypher code (passed to Cycli
or cypher-shell
):
LOAD CSV WITH HEADERS FROM "file:/glycolysis_relations.csv" AS row
MERGE (s:Glycolysis {source: row.source})
MERGE (r:Glycolysis {relation: row.relation})
MERGE (t:Glycolysis {target: row.target})
FOREACH (x in case row.relation when "substrate_of" then [1] else [] end |
MERGE (s)-[r:substrate_of]->(t)
)
FOREACH (x in case row.relation when "yields" then [1] else [] end |
MERGE (s)-[r:yields]->(t)
);
I'd like to create the fully-connected pathway, with captions on all the nodes. Suggestions?
[UPDATED]
There are multiple issues and possible improvements:
MERGE
should be deleted, since it creates orphaned nodes. A relationship type should not be tuned into aGlycolysis
node, and such nodes would never be connected to any other nodes.MERGE
clauses must use the same property name (say,name
) for source and target nodes, or else the same chemical can end up with 2 nodes (with different property keys). This is why you ended up with nodes that did not have all the expected connections.MERGE
of relationships with dynamic names.glycolysis_bioentities.csv
is not needed for this use case.With the above changes, you end up with something like this, which will generate a connected graph that matches your input data:
@cybersam's answer is excellent, providing the most elegant solution (once again: thank you!) -- please upvote that accepted answer.
Since this question/answer/topic is likely to be of interest to others, I wanted to mention that my code (based on this SO thread, How to specify relationship type in CSV?, and modified per the hints provided by @cybersam) now works, and show the result:
Solution 1 (my original post, updated):
Solution 2 (cybersam's, updated):
Both solutions generate the identical graph, below. :-D
If permitted, I'd like to post one more follow-on answer -- my reason being that currently there is very little out there on recreating metabolic pathways in Neo4j, and the following will provide a complete summary under this StackOverflow title/subject, "Creating a metabolic pathway in Neo4j".
Like my Glycolysis pathway, above, I recreated in Neo4j the TCA (citric acid cycle | Kreb's cycle) pathway:
[TCA cycle image source: https://metabolicpathways.stanford.edu/]
An issue that arose during the creation of my TCA pathway graph was that the one of the nodes (the enzyme, "aconitase") was used twice, so during the graph creation
MERGE
merged the common nodeaconitase
as a single entity, resulting in this layout,... not this one, as desired,
My solution to that issue was to create the "TCA graph" using node properties, to temporarily differentially-tag the affected source and target nodes (later removing those tags, after the graph was properly created).
I also added a
:Metabolism
label, so that I could select the individual pathways (:Glycolysis
|:TCA
) or the complete metabolic network (:Metabolism
), as desired.Lastly, I needed to connect the two pathways (
:Glycolysis
|:TCA
) through their common node,pyruvate
, which I was able to do through an APOC procedure (here, appended to the end of myglycolysis.cql
(Cypher) script.Here are my CSV data files, *.cql Cypher scripts, script execution, and the resultant graph.
glycolysis.csv:
tca.csv:
"tag1" and "tag"2 in "tsv.csv" are used to uniquely those source and target nodes, when they are created via the "tca.cql" script:
tca.cql:
glycolysis.cql:
Script execution:
Neo4j graph (
:Metabolism
view):