Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
07-14-2020 02:14 PM
I have some properties that are linked together by one common meta-property. So consider this ( it does NOT work - I know that)
CREATE (n:Person { name: 'Andy', title: 'Developer', listKey: [{ inner1: 'Map1' }, { inner2: 'Map2' }] })
The goal is to be able to manipulate this much like a dictionary in python or even a map. I could make them all properties
CREATE (n:Person { name: 'Andy', title: 'Developer', Inner1: 'Map1', Inner2: 'Map2' })
but that rather makes grouping (e.g. listKey) impossible.
This variant (straight up list) didnt work either -
CREATE (n:Person { name: 'Andy', title: 'Developer', listKey: [ inner1: 'Map1', inner2: 'Map2' ] })
While these two are pretty clumsy, they work. But they require the developers to "unpack"
CREATE (n:Person { name: 'Andy', title: 'Developer', listKey: [" inner1: 'Map1", " inner2: 'Map2'"] })
CREATE (n:Person { name: 'Andy', title: 'Developer', listKey: " [ inner1: 'Map1', inner2: 'Map2' ]" })
This works, and the java developers could at least create a Map structure, but makes the pure cypher developers a bit crazed ( not even sure how they would address the values)
CREATE (n:Person { name: 'Andy', title: 'Developer', listKeyN: [" inner1", " inner2"] , listKeyV:['Map1','Map2']})
I've seen some recommendation to add nodes and rel but given that I have 3m nodes, multiplying it by 20 doesn't seem smart. Although I could name the relationships listKey and walk the set.
Any other choices ? Is this something I should be doing in APOC ?
Thanks
07-14-2020 02:38 PM
May be considered a lame method, but still... JSON may be useful in your particular case.
Storing the listKey
as a single String property and using apoc.convert.toJson
/ apoc.convert.fromJsonList
/ apoc.convert.fromJsonMap
to manipulate its contents.
I'm also interested if anyone comes with something better
07-14-2020 09:26 PM
Hello @bill.dickenson,
This line is the right way:
CREATE (n:Person { name: 'Andy', title: 'Developer', Inner1: 'Map1', Inner2: 'Map2' })
Otherwise, as said by @m-zielinski, store as JSON is a good option.
You can get on this page the values and type you can store as properties
Regards,
Cobra
07-15-2020 06:51 AM
So far, you may be right. It just makes it easier for the UI developers to pick on different "listkey" groups in the interface rather than have to look it up. So if we move a variable from one group to another, we have to rely on documentation, and not just let them pull listkey1, listkey2 and use the structure to dictate what variables pop up. The closest we have come, is to create 3 "subnodes" for each and then link them through the main node.
Then the developers at least know to walk the set (e.g listkey2) but the mechanics of creating new nodes and managing seems cumbersome also. (especially through APOC) .
Are there any examples of using APOC and JSON functionality available publicaly ?
07-16-2020 06:42 AM
While not the optimal solution, we have almost settled in on two linked lists,
CREATE (n:Person { name: 'Andy', title: 'Developer', listKey1Name: [" inner1", " inner2"] , listKey1Value:['Map1','Map2'],listKey2Name: [" inner3", " inner4"] , listKey2Value:['Map3','Map4']})
It's a compromise, since the developers can have a UI element (listKey1, listKey2) that can be exploded (think "+") into elements
(-) listKey1
inner1:map1
inner2:map2
(+) listkey2
06-07-2022 11:30 PM
This is the best solution!
07-16-2020 06:49 AM
How did you store the data in the nodes?
Can you print the content of a node?
07-16-2020 07:19 AM
Right now, we store it as a big string and then parse in java. Focus on the listKey strings.
{
"identity": 1,
"labels": [
"Label",
"ProgNode",
"data:Reads"
],
"properties": {
"level": "code",
"ctx": "1891845967",
"Label": "data:Reads",
"FILECOUNT": 1,
"listKey1": "{'time':0, 'calls':0, 'score':0}",
"listKey2": "{'reusescore':0, 'called':0, 'score':0}",
"type": "typeImportOnDemandDeclaration",
"EIEO": true,
"inode": "1",
"node": "1",
"location": [
16,
0,
16,
17
],
"text": "importjava.net.*;",
"changed": false
}
}
In a perfect world, we would not have to do this but this is the structure the UI developers and the rule developers have agreed on. It would replace listkey1, listkey2 with something like
"listKey1Name": ['time','calls','score'],
"listKey1Value": [0,0,0],
which could be zip into a single key:value list for the UI (referring to the zip(list, list, list) call that combines lists)
Thanks
07-16-2020 09:51 AM
Of course now I need to figure out how to access the listKey1Value list in cypher - so not ideal.
07-17-2020 02:44 PM
Might have a huge overhead and cypher complexity, but how about having one node for each property type (like time), and, for each node that would have had that property in the map, a relationship with that node. And then use a relationship property with the value of that field.
Null properties could be represented as no relationship, and you can still perform queries using the operators on the relationship values.
Like, one single node for "time" property type, and a generic val property with in each relationship with nodes that have that property in the map?
I hope this helps.
Cheers,
02-07-2021 06:43 PM
I say you treat the Graph DB as a Graph DB, and create a linked list of nodes faithfully represented as nodes and arrows in the global graph itself.
class LinkedListNode(StructuredNode):
uid = UniqueIdProperty()
next_uid = StringProperty()
data_uid = StringProperty()
That is the neomodel code to do this. 😄 I am having some success with Django + associated neomodel libraries in Python.
02-07-2021 07:01 PM
Tried that. It increased (slowed down) the system about 15-18% so it wasn't viable. But thanks for following up !
02-08-2021 12:35 AM
Hello
It looks like that now you can store homogeneous type lists, for example: list of integers, list of strings or list of Points.
Regards,
Cobra
02-08-2021 07:08 AM
Yes, thank you. That was exactly how we ended up solving the problem. It was much simpler.
03-04-2021 05:18 PM
@bill.dickenson @Cobra where have you seen that?
When checking the 4.2 documentation, it says:
Cannot be stored as properties
EDIT: how, my bad... I've now found it in "Property types"
Homogeneous lists of simple types can also be stored as properties, although lists in general (see Composite types) cannot be stored.
03-04-2021 05:27 PM
But as Cobra said, its homogeneous - so no mixed int/string lists. That wasn't fatal, we just made everything a string and converted the ones that were really integers on the back end.
All the sessions of the conference are now available online