質問

My graph contains nodes called points and lines.

There is a relationship type called "NEXT", which connects two points and has a property called lineID (a long). A line node consists simply of an ID and a reference to a "root" point. To traverse a line is to start with its root node and follow the NEXT relationships whose lineID matches the id of the line being traversed. To clarify, if we're traversing a line with ID 123, whose root point has id 321, the Cypher traversal would be:

 START n = node(321) 
 MATCH (n)-[rel:NEXT*{lineID:123}]->(x) 
 RETURN collect(rel)

A line, then, is essentially a linked list of Next relationships with matching lineID properties. That said, I don't want to persist this list as a property of lines - I want the list to be constructed by a traversal when a line is loaded.

What are my options for implementing this in spring-data-neo4j? Specifically, should "lines" exist as NodeEntitys, and if so what should they contain?

@NodeEntity
class Line {
    @RelatedTo(type="ROOT")
    Point root;
    @RelatedToVia(type="NEXT") 
    Iterable<Item> list;

doesn't quite fit, because the line is not related via Next relationships to the item, the root point is. It also fails to address the fact that those NEXT relationships need to have a lineID property matching the line's ID (which becomes important because some points exist on multiple lines - i.e. they have multiple NEXT relationships with different lineID's). I have a hunch that the solution will involve annotating the list as a @GraphTraversal, but I don't understand how that would work.

I'm doing this largely as an exercise to wrap my head around data modeling in SDN, in the context of wrapping my head around Neo4j and graph databases in general. If the question I'm asking reveals a flaw in my understanding of any of these things, I'd be very appreciative if someone could point it out.

役に立ちましたか?

解決

This should be a suitable model for your entities:

@NodeEntity
class Point {
    @GraphId
    protected Long id;

    @RelatedToVia(type="NEXT")
    Set<Edge> edges;
}

@NodeEntity
class Line {
    @GraphId
    protected Long id;

    @RelatedTo(type="ROOT")
    Point root;
}

@RelationshipEntity
public class Edge  {
    @GraphId
    protected Long id;

    @StartNode private Point from;
    @EndNode private Point to;

    @RelatedTo(type="LINE")
    Line line;
}

It easily allows both programmatic navigation in Java as in:

Set edges = line.getPoint().getEdges();

for (Edge edge: edges) {
    if (edge.getLine().getId() == id) {
        ...
    }

}

or Cypher queries like the one you listed.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top