Modeling an ordered tree with neo4j

I'm just starting out with neo4j, and I understand the principles of graphics and relationships, but I have a bit of a problem with some of the structures that I want to model. I wanted to use it in a programming language project and store the AST in the analyzed source file. From there, I plan to add a lot of additional data and relationships to the nodes to help with analysis and tools, but the fundamental AST is still a bit difficult.

A naive way to create a tree would be to simply go through the AST and copy each node to the tree on the node in neo4j, using properties to track token data, etc., and then use the BABY to point to the child nodes. The problem is that when I later want to cross the tree, I will need to do this in the correct order of the original AST, but out of the box I'm not quite sure what the best way to do this.

I have two main approaches that I recall. One of them is to simply add the index / ordinal property for each CHILD relationship. The other must have a FIRST relationship to the first child and a NEXT relationship between each child to maintain order in this way.

For any of these approaches, it still doesn't seem that there is something out of the box that I can use to cross it in the correct order. I think that if I do FIRST / NEXT, I can get the correct order as long as I get neo4j to always cross FIRST first and do the first depth search. Will this work? Is there a better way? It seems like it should be easier to handle the task.

UPDATE

In the end, I decided to use both of my ideas. Child nodes have a CHILD relationship with the index property. The first child also has a FIRST_CHILD relationship. Sibling nodes have a NEXT_SIBLING relationship to give the correct order. After that, the workaround was simple:

//reusable traversal description final private TraversalDescription AST_TRAVERSAL = Traversal.description() .depthFirst() .expand(new OrderedByTypeExpander() .add(RelType.FIRST_CHILD, Direction.OUTGOING) .add(RelType.NEXT_SIBLING, Direction.OUTGOING)); 

and then when I really needed to walk on a tree, I could just do

 for(Path path : AST_TRAVERSAL.traverse(astRoot)){ //do stuff here } 

In my use case, I actually do not modify the tree structure after creation - I just do the analysis and add more relationships and properties, so it’s easy to maintain. If I had to make more changes, this might be a bit of work, especially if I want to maintain index numbers in child relations. So it may be something that you might think for someone else in a similar situation.

If I were to fall into something more volatile, I would most likely try the collections suggested by Peter Neubauer, and probably just create an OrderedTreeNode class pointing to a node and using the List collection for children.

+6
source share
2 answers

Russel, we work on such things, we have an ordered tree of time in works that are structured along lines of different YEAR-2012-> MONTH-01-> DAY-21-> VALUE123 and will probably have NEXT relationships between, for example, MONTHS of the same year.

Otherwise, if you do, consider contributing or exploring the material at https://github.com/neo4j/graph-collections , the contribution and testing is highly appreciated there!

+1
source

In the interest of anyone who finds this more than two years later, finally, there is a library that supports time trees out of the box (disclaimer: I am one of the authors):

https://github.com/graphaware/neo4j-timetree

+1
source

Source: https://habr.com/ru/post/907315/


All Articles