Naming convention for bidirectional relationships

2019-06-05 07:07发布

问题:

I need some advice to give name to relationships. Plus, I'm not sure on how I have to annotate my domain entities with spring data. Most of examples that I've seen are unidirectional and the name chosen are pretty straightforward.

Supose the following example:

@NodeEntity
public class Person {   
    @Indexed
    private String name;

    @RelatedTo(type="OWNS", direction=Direction.OUTGOING)
    private Set<Car> cars;
} 

The relationship name seems ok, no problem.

Now suppose that I want to make this relationship bidirectional. What are the differences (and the pros/cons) of the following approaches.

1) Make both sides of the relationship direction=Direction.BOTH and call the relationship type="OWNERSHIP"?

@NodeEntity
public class Person {   
    @Indexed
    private String name;

    @RelatedTo(type="OWNERSHIP", direction=Direction.BOTH)
    private Set<Car> cars;
}

@NodeEntity
public class Car {   
    @Indexed
    private String description;

    @RelatedTo(type="OWNERSHIP", direction=Direction.BOTH)
    private Person person;
}

2) Use direction on both sides?

@NodeEntity
public class Person {   
    @Indexed
    private String name;

    @RelatedTo(type="OWNS", direction=Direction.OUTGOING)
    private Set<Car> cars;
}

@NodeEntity
public class Car {   
    @Indexed
    private String description;

    @RelatedTo(type="OWNED_BY", direction=Direction.INCOMING)
    private Person person;
}

回答1:

There is no such thing as bidirectional relationships in Neo4j. Each relationship has a start node and an end node. That said, you can choose to ignore that direction when writing traversals, effectively using the relationship as a bidirectional one.

What you're trying to model is people owning cars. (person) -[:OWNS]-> (car) means two things: from the person's point of view, this outgoing relationship shows the person owns the car. From the car's point of view, the very same (but incoming) relationship means it is owned by the person.

The @RelatedTo annotation in SDN uses Direction.OUTGOING by default, if no direction is specified. This is why you might have thought these relationships are bidirectional, but they are not; they are OUTGOING by default.

So I would model your domain like this:

@NodeEntity
public class Person {   
   @Indexed
   private String name;

   @RelatedTo(type="OWNS", direction=Direction.OUTGOING) //or no direction, same thing
   private Set<Car> cars;
}

@NodeEntity
public class Car {   
   @Indexed
   private String description;

   @RelatedTo(type="OWNS", direction=Direction.INCOMING)
   private Person person;
}