Neo4J节点和关系:我是否必须将所有内容建模为节点?

时间:2014-11-02 19:49:15

标签: neo4j relationship nodes spring-data-neo4j

我正在尝试将Neo4J与Spring Data一起使用,但我不确定我的设计是否正确(我第一次使用图形数据库)。 问题是我不知道我是应该将所有内容建模为Node还是仅仅是一个简单的属性。

示例:(我最大的节点)

@NodeEntity
public class User{

@Indexed(unique=true)
private String username;
@Indexed(unique=true)
private String email;

// Is a node ???
private Location location

private int areaRadius;

//No need to create a rich relationship
@RelatedTo(type=RelationshipTypes.LIKES, direction=Direction.OUTGOING)
@Fetch
private Set<Hobby> hobbies = new HashSet<Hobby>;

//No need to create a rich relationship
@RelatedTo(type=RelationshipTypes.HAS_CATEGORY, direction=Direction.OUTGOING, elementClass=Category.class)
@Fetch
private Set<Category> favCategories = new HashSet<Category>;

//Must create a rich relationship (Friendship.java)
@RelatedTo(type=RelationshipTypes.FRIEND_OF, direction=Direction.BOTH)
@Fetch
private Set<User> friends = new HashSet<User>;

//Rich relationship between Users (Friendship.java)
@RelatedToVia(type=RelationshipTypes.FRIEND_OF)
@Fetch
private Set<Friendship> friendships = new HashSet<Friendship>;

//Must create a rich relationship (UserEvent.java)
@RelatedTo(type=RelationshipTypes.GOING_TO, direction=Direction.OUTGOING)
@Fetch
private Set<Event> events = new HashSet<Event>;

//Rich relationship between Users (UserEvent.java)
@RelatedToVia(type=RelationshipTypes.GOING_TO)
@Fetch
private Set<UserEvent> userEvents = new HashSet<UserEvent>;

// Is a node ???
private Set<Status> statusList;

private URI profilePicture;

public User(){}

public User(String username, String email, Location location){
    this.username = username;
    this.email = email;
    this.location = location;
}

public void addHobby(Hobby hobby){
    this.hobbies.add(hobby);
}

public void sendFriendRequestTo(User user){
    this.friendships.add(new Friendship(this, user, Friendship.REQUESTED);
}

public void addCategory(Category category){
    this.favCategories.add(category);
}

public void addConfirmedEvent(Event event){
    this.userEvents.add(new UserEvent(this, event, false));
}

public void addMaybeEvent(Event event){
    this.userEvents.add(new UserEvent(this, event, true);
}

}

我的问题是:

1)我是否必须将状态和位置建模为节点?

  • 状态将包含:String text, Set<String> tags, Date date
  • 位置将包含:country, city, postalCode, double[] coordinates.

2)我不明白如何使用Spring Data存储相关节点:

  • 我是否只需要存储与@RelatedToVia
  • 的关系
  • 或者我是否只需要存储@RelatedTo
  • 的相关节点
  • 或者我是否需要同时存储

3)当我添加一部喜欢的电影时,我该怎么做:

  • 将其添加到likedMovies Set? (这种关系会自动创建吗?)
  • 将其添加到relationship Set(例如评分)? (然后,LikeMovies Set将在下次获取时自动更新)
  • 在两者中添加?

4)对于朋友Set和友谊集,我是否必须指定相同的类型(type =)?

编辑:

新问题:

5)如果我有相同的关系,但有不同的@StartNodes(用户有类别,但电影也有类别)。我是否必须使用不同的@StartNode创建2个@RelationshipEntity? (在这种情况下,这不是一个丰富的关系)。

1 个答案:

答案 0 :(得分:1)

  1. 你应该只模拟真正的实体,比如Venue和一个位置字段。 如果您连接更多位置,位置是有意义的。

  2. 这取决于您的模型,如果您的关系非常丰富,您可以使用@RelatedToVia,但您不必这样做。查看您的实体而不是某些用例的预测,而不是&#34;一个尺寸适合所有用户&#34;最后会咬你的。

  3. 如果你有丰富的关系,你应该将它们添加到@RelatedToVia集。要获得更快的方法,您还可以使用template.createRelationshipBetween()。或者只是创建RelationshipEntity,分配起始端节点和属性,并使用template.save()保存它。

  4. 是的,注释中的关系类型相同

  5. 你有一个&#34;富人&#34;与类别的关系?如果不是,你不必为它建模。如果是,那会是什么样子?那么也许不同类型的类别关系是有意义的(也有不同的rel类型)

  6. 这取决于您的型号和您的用例 尽可能删除@Fetch注释,它只会加载您可能不需要的大量数据。如果需要,请使用template.fetch(user.field)

  7. 对于许多用例,我建议不要从数据库中加载和保湿完整实体,而是运行查询并将返回的最小数据量投影到视图对象/ dto的列表中(带注释)或者派生的)存储库方法和POJO上的@QueryResult