Skip to content

Commit 7963c5f

Browse files
committed
json to cypher concepts
1 parent 36dfb76 commit 7963c5f

File tree

5 files changed

+126
-41
lines changed

5 files changed

+126
-41
lines changed

README.md

+82-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,88 @@
1-
# neo4j
1+
# json to cypher
2+
* graph data formats : comparing multiple representations formats of the same graph, cypher offers an impressively compact and comprehensible notation. Unfortunately, cypher is a domain specific language, therfore automated import and export requires a native json format that offers generic hierarchical maps of lists.
3+
Therefore, the goal is to provide utilities that can convers multiple json formats that are conetnt agnostic into cypher.
4+
* native data structures : Applications usually do know the relations between the data structures therefore tend to optimize the data export and do not embed explicit relations in the data structures, that results in a more packed data than if an explicit list of nodes and edges has to be created.
5+
6+
![json formats](./json%20formats.svg)
7+
8+
* jsonl : json lines is very effitient when it comes to scale as every line can be processed separately without loasing the whole file in memory, such scale is outside of scope of this repo that targets applications that fit and can be processed in memory.
9+
* neo4j ids : althoug neo4j db has a unique id among all Lebel types, within the export, every Label has its own id scope, therefore when referencing a target within edges, the label has to be provided as well.
10+
* no ids : json data exchanged between applications should not contain app specific number ids because the import or append in an existing database will require assignment of new ids. Additionally, data created manually by users or other apps requires an additional effort to add those ids.
11+
* unique ids : The scope of these loading utilities is to deal with data where all members of every group can be uniquely identified with one of their properties that is human comprehensible such as name. If such a restriction is not possible, then a custom cypher will have to be written and automated json load cannot be used without given uids. Note that the name is used by neo4j as a Label (Text visualization) neo4j reserves the Label for the type and uses name instead.
12+
* uid maps, no lists : every group of data should be structured in a map, not a list, where the uid is used as a key
13+
* Labels are the terms used by neo4j for node types. inported data will not take advantage of multi typing capabilities of neo4j. Fallback on a single type allows to pack all data of the same type in a map where the key is the type of the nodes
14+
15+
examples of `Packed json` : see `data\packed.json` and `data\zigbee_packed.json`
16+
```json
17+
{
18+
"Persons":{
19+
"Michael":{
20+
"age": 41,
21+
"Persons":[
22+
"Selina",
23+
"Rana",
24+
"Selma"
25+
]
26+
},
27+
"Selina":{},
28+
"Rana":{},
29+
"Selma":{}
30+
}
31+
}
32+
```
33+
34+
examples of `Mapped relations json` : see `data\persons_mapped_relations.json` and `data\programmers_mapped_relations.json`
35+
36+
```json
37+
{
38+
"Persons":{
39+
"Michael":{
40+
"age": 41,
41+
"knows":{
42+
"Persons":[
43+
"Selina",
44+
"Rana",
45+
"Selma"
46+
],
47+
},
48+
"children":{
49+
"Persons":[
50+
"Rana",
51+
"Selma"
52+
]
53+
}
54+
},
55+
"Selina":{},
56+
"Rana":{},
57+
"Selma":{}
58+
}
59+
}
60+
```
61+
62+
## Packed vs mapped relations
63+
* a `packed json` has minimal footprint and prevents redundancies as names of relations are usually not needed or known by the application using the data
64+
* a `mapped relations` is fully informative with regards to the relationship type, as it adds an extra step of grouping all relationship tapes in a map with the relationship Label as the key
65+
* a `packed json` can hava an optional file separate from the main data that Labels the relationships depending on the source and target
66+
67+
example relations labels see also `data\zigbee_optional_relations.json`
68+
```json
69+
{
70+
"Persons":{
71+
"Persons":"knows"
72+
}
73+
}
74+
```
75+
* only a `mapped relations` allows to have different relationship types between the same node types
76+
* a combination of both `packed json` and `mapped relations` is possible with automated identification depending on the property type (list, map) and its availability in the top node Types map.
77+
* both `packed json` and `mapped relations` can have target relation items as either a list of a map
78+
* a list a simpler in case the relation does not have any property
79+
* a map is needed if relatioships do have properties. The key is then the target and the value is a map of properties (see `data\persons_mapped_relations.json` with mapped relations weight)
80+
81+
# neo4j usage
282
* Cypher : Graph Query Language
383
* apoc : Awesome Procedures On Cypher
484
* gds : Graph Data Science
5-
## note
6-
Please refer to the official links for latest documentation, this repo is only a sort of cheat sheet and contains history of commands I tested
85+
786
# run
887
- docker: simply run `./run.sh` which content is
988
```shell
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,4 @@
11
{
2-
"_relationships":[
3-
{
4-
"start":"Labels1",
5-
"end":"Labels2",
6-
"label":"rel_action"
7-
},
8-
{
9-
"start":"Labels2",
10-
"end":"Labels3",
11-
"label":"contains"
12-
},
13-
{
14-
"start":"Labels3",
15-
"end":"Labels4"
16-
},
17-
{
18-
"end1":"Labels4",
19-
"end2":"Labels5",
20-
"label":"knows"
21-
},
22-
{
23-
"end1":"Labels5",
24-
"end2":"Labels6"
25-
}
26-
],
272
"Labels1":{
283
"Name1":{
294
"property1": "lifo",
@@ -52,16 +27,3 @@
5227
"kitchen":{ }
5328
}
5429
}
55-
56-
57-
58-
59-
60-
61-
62-
63-
64-
65-
66-
67-
File renamed without changes.

json formats.dio

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<mxfile host="65bd71144e">
2+
<diagram id="H196RScLTJ84AIABPyfc" name="Page-1">
3+
<mxGraphModel dx="323" dy="718" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" background="#ffffff" math="0" shadow="0">
4+
<root>
5+
<mxCell id="0"/>
6+
<mxCell id="1" parent="0"/>
7+
<mxCell id="2" value="Packed&lt;br&gt;(App Native)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
8+
<mxGeometry x="50" y="100" width="120" height="60" as="geometry"/>
9+
</mxCell>
10+
<mxCell id="3" value="Mapped relations" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
11+
<mxGeometry x="240" y="100" width="120" height="60" as="geometry"/>
12+
</mxCell>
13+
<mxCell id="6" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=#030303;" parent="1" source="4" target="2" edge="1">
14+
<mxGeometry relative="1" as="geometry"/>
15+
</mxCell>
16+
<mxCell id="4" value="Optional Relations Labels" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
17+
<mxGeometry x="50" y="190" width="120" height="30" as="geometry"/>
18+
</mxCell>
19+
<mxCell id="9" value="Node Edge Lists" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
20+
<mxGeometry x="430" y="100" width="120" height="60" as="geometry"/>
21+
</mxCell>
22+
<mxCell id="10" value="" style="shape=flexArrow;endArrow=classic;html=1;fontSize=18;fontColor=#171717;strokeColor=none;fillColor=#A1A1A1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="11" edge="1">
23+
<mxGeometry width="50" height="50" relative="1" as="geometry">
24+
<mxPoint x="60" y="30" as="sourcePoint"/>
25+
<mxPoint x="380" y="30" as="targetPoint"/>
26+
</mxGeometry>
27+
</mxCell>
28+
<mxCell id="11" value="Graph" style="text;strokeColor=none;fillColor=none;html=1;fontSize=24;fontStyle=0;verticalAlign=middle;align=center;fontColor=#171717;" parent="1" vertex="1">
29+
<mxGeometry x="440" y="10" width="100" height="40" as="geometry"/>
30+
</mxCell>
31+
<mxCell id="12" value="" style="shape=flexArrow;endArrow=classic;html=1;fontSize=18;fontColor=#171717;fillColor=#A1A1A1;strokeColor=none;" parent="1" edge="1">
32+
<mxGeometry width="50" height="50" relative="1" as="geometry">
33+
<mxPoint x="540" y="70" as="sourcePoint"/>
34+
<mxPoint x="180" y="70" as="targetPoint"/>
35+
</mxGeometry>
36+
</mxCell>
37+
<mxCell id="13" value="App Native" style="text;strokeColor=none;fillColor=none;html=1;fontSize=24;fontStyle=0;verticalAlign=middle;align=center;fontColor=#171717;" parent="1" vertex="1">
38+
<mxGeometry x="60" y="50" width="100" height="40" as="geometry"/>
39+
</mxCell>
40+
</root>
41+
</mxGraphModel>
42+
</diagram>
43+
</mxfile>

json formats.svg

+1
Loading

0 commit comments

Comments
 (0)