【发布时间】:2012-12-17 17:02:51
【问题描述】:
开始着手一个新项目... RESTful 层为社交网络平台提供服务。
Neo4j 是我主要数据存储的明显选择,我之前有机会与 Neo 合作,但没有利用 Spring Data 功能将 POJO 映射到似乎很方便的节点。
目标:
该层应该提供类似于 Facebook Graph API 的支持,它为每个 entity/object 定义了可以从 URL 引用的相关属性和连接。
FB Graph API如果可能,我想避免传输将被序列化到域实体/从域实体传输的对象,并使用我的域 pojo 作为 JSON 传输到/从客户端传输。
示例:
HTTP GET /profile/{id}/?fields=...&connections=... 响应将是 Profile 对象包含请求的 URL。
HTTP GET /profile/{id}/stories/?fields=..&connections=...&page=..&sort=...根据请求,响应将是 Story 对象的列表。
相关版本:
- Spring 框架3.1.2
- Spring Data Neo4j 2.1.0.RC3
- Spring Data Mongodb 1.1.0.RC1
- AspectJ 1.6.12
- 杰克逊1.8.5
为了简单起见,我们有简介、故事节点和角色 它们之间的关系。
public abstract class GraphEntity {
@GraphId
protected Long id;
}
配置文件节点
@NodeEntity
@Configurable
public class Profile extends GraphEntity {
// Profile fields
private String firstName;
private String lastName;
// Profile connections
@RelatedTo(type = "FOLLOW", direction = Direction.OUTGOING)
private Set<Profile> followThem;
@RelatedTo(type = "BOOKMARK", direction = Direction.OUTGOING)
private Set<Story> bookmarks;
@Query("START profile=node({self}) match profile-[r:ROLE]->story where r.role = FOUNDER and story.status = PUBLIC")
private Iterable<Story> published;
}
故事节点
@NodeEntity
@Configurable
public class Story extends GraphEntity {
// Story fields
private String title;
private StoryStatusEnum status = StoryStatusEnum.PRIVATE;
// Story connections
@RelatedToVia(type = "ROLE", elementClass = Role.class, direction = Direction.INCOMING)
private Set<Role> roles;
}
角色关系
@RelationshipEntity(type = "ROLE")
public class Role extends GraphEntity {
@StartNode
private Profile profile;
@EndNode
private Story story;
private StoryRoleEnum role;
}
起初我没有使用 AspectJ 支持,但我发现它对我的用例非常有用,因为它在 POJO 和实际节点之间生成分隔符,因此我可以轻松请求属性/connections 根据请求和Domain Driven Design Approach 看起来很不错。
问题 1 - AspectJ:
假设我想为一个对象定义默认字段,无论是否在 URL 中请求,这些字段都将返回给客户端......所以我尝试了 @FETCH 注释这些字段,但它似乎在使用 AspectJ 时不起作用。
目前我是这样做的..
public Profile(Node n) {
setPersistentState(n);
this.id = getId();
this.firstName = getFirstName();
this.lastName = getLastName();
}
这是实现这一目标的正确方法吗?即使使用 AspectJ,是否也应该支持 @FETCH 注释?
我很乐意看到有关 AspectJ + Neo4j 的示例/博客几乎没有找到任何东西....
问题 2 - 分页:
我想在请求特定连接时支持分页,例如
/profile/{id}/stories/,如果故事相关如下
// inside profile node
@RelatedTo(type = "BOOKMARK", direction = Direction.OUTGOING)
private Set<Story> bookmarks;
/profile/{id}/stories/,如果故事相关如下
// inside profile node
@Query("START profile=node({self}) match profile-[r:ROLE]->story where r.role = FOUNDER and story.status = PUBLIC")
private Iterable<Story> published;
@Query 是否支持开箱即用的分页 || @RelatedTo || @RelatedToVia 使用 Pageable 接口来检索 Page 而不是 Set/List/Iterable?限制和排序应该是动态的,具体取决于客户端的请求...我可以使用Cypher Query DSL 实现这一点,但更喜欢使用基本的.. 其他方法将被愉快地接受。
问题 3 - @Query 与 {self}:
有点愚蠢的问题,但我忍不住 :),似乎在节点实体内使用 @Query 时(使用 {self} 参数},返回类型必须是 Iterable,这很有意义.. 让我们举个例子......
// inside profile node
@Query("START profile=node({self}) match profile-[r:ROLE]->story where r.role = FOUNDER and story.status = PUBLIC")
private Iterable<Story> published;
当请求发布连接时:
// retrieving the context profile
Profile profile = profileRepo.findOne(id);
// getting the publishe stories using AspectJ - will redirect to the backed node
Iterable<Story> published = profile.getPublished();
// set the result into the domain object - will throw exception of read only because the type is Iterable
profile.setPublished(published);
有解决办法吗?这不会创建另一个属性,该属性将是 Profile 中的 @Transiant ..
问题 4 - 递归关系:
我在传递/递归关系方面遇到了一些问题,当在 Story 中分配新的 Profile Role 时,关系实体角色包含 @EndNode story ,其中包含 roles connection.. .其中之一是上面的上下文role,它永远不会结束:)... 有没有办法配置弹簧数据引擎不创建这些永无止境的关系?
问题 5 - 交易:
也许我之前应该提到过它,但我正在使用 Neo4j DB 的 REST 服务器,从之前的阅读中我了解到事务中不支持开箱即用?就像使用嵌入式服务器时一样 我有以下代码...
Profile newProfile = new Profile();
newProfile.getFollowThem().add(otherProfile);
newProfile.getBookmarks().add(otherStory);
newProfile.persist(); // or profileRepo.save(newProfile)
当使用 REST 服务器时,这会在事务中运行吗?这里的操作很少,如果一个失败就失败了?
问题 6 - Mongo + Neo4j:
我需要存储不具有关系性质的数据。例如 Feed、评论、按摩。
我考虑过与 MongoDB 集成来存储这些数据。我可以拆分域吗pojo 字段/连接到具有跨商店支持的 mongo/neo4j?它会支持 AspectJ 吗?
现在就是这样......任何关于我上面介绍的任何方法的 cmet 都将受到欢迎......谢谢。
【问题讨论】:
-
哇,问题太多了。
标签: social-networking neo4j aspectj spring-data-neo4j spring-data-mongodb