Spring 数据 REST Neo4j 创建关系
Spring Data REST Neo4j create a relationship
我正在开发一个ui小测试应用程序作为学习 Angular 和在很多 Spring 堆栈上刷新自己的方式。我对 Neo4J 有一些小经验,但应用程序的想法已经有了像 Neo4j 这样的图形数据库。
这个想法非常简单,ui 创建角色和故事,将角色与故事以及彼此联系起来,映射他们各自的故事版本,并创建一些图表来显示角色互动帮助撰写整体叙述。
我已经足够轻松地获得角色和故事的节点,Spring 堆栈非常适合让我轻松地使用节点本身的休息端点。但是我找不到任何创建和维护这些节点之间关系的具体示例。
例如,在 Cypher 中,我可以将一个角色与一个故事联系起来,并将该人物与故事的关系描述为一种关系 属性 与:
match(p:Being ),(s:Story ) where id(p) = 7 and id(s) = 16
create (p)-[r:TOOK_PART_IN{perspective:"I did not know Mr. Grey better than an acquaintance, though I knew others whom did. They were not made better because of their relationship with him."}]->(s) return r
然后使用 Spring 中的映射,我从 REST 端点返回的数据为我提供了我的角色,我可以按照 link 获取该角色所属的故事。我没有看到 post 或从故事中添加或删除角色的方法。
我也只是在 Spring 的文档中找到关于节点的具体示例,而不是 edges/relationships。谁能提供这样的东西?
我完全知道 Neo4J 有它自己的 REST 接口,这基本上也是 Spring 正在使用的。本次练习的主要目的是学习一些新技术(Angular2/typescript)和刷新我对Spring栈的知识
谢谢!
我不确定是否有其他人对此找到了好的或更好的答案,但这是我找到的有效答案。我有一个 spring 引导项目 运行,我将 post 在此答案中提供一些最相关的代码和示例,但要查看整个 REST 服务项目,请检查 https://github.com/jrspriggs/Chronicler
因此,小应用程序的目的 atm 是创建 characters/beings 参与故事,创建故事(具有标题和 slug 线)并创建存在与故事之间的关系存在对与这种关系相关的故事的看法。这样它就收集了每个角色故事的不同版本。
neo4j 实例只是我 Windows 笔记本电脑上 Docker/Kitematic 中的一个基本 neo4j 实例。以下是型号:
Being.java:
package com.chronicler.model;
import java.util.Iterator;
import java.util.Set;
import org.springframework.data.neo4j.annotation.Fetch;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.annotation.RelatedToVia;
@NodeEntity
public class Being {
public Long getId() {
return id;
}
@GraphId private Long id;
private String firstName;
private String lastName;
private boolean hero;
private boolean villain;
@RelatedToVia(type="TOOK_PART_IN")
@Fetch private Set<Involvement> involvements;
public Set<Involvement> getInvolvements() {
return involvements;
}
public void setInvolvements(Set<Involvement> involvements) {
this.involvements = involvements;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public boolean isHero() {
return hero;
}
public void setHero(boolean hero) {
this.hero = hero;
}
public boolean isVillain() {
return villain;
}
public void setVillain(boolean villain) {
this.villain = villain;
}
}
Story.java
package com.chronicler.model;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.NodeEntity;
@NodeEntity
public class Story {
public Long getId() {
return id;
}
@GraphId private Long id;
private String title;
private String slug;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
}
Involvement.java(与故事的关系)
package com.chronicler.model;
import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.Fetch;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.StartNode;
@RelationshipEntity(type="TOOK_PART_IN")
public class Involvement {
@GraphId private Long relationshipId;
@Fetch @StartNode private Being being;
@Fetch @EndNode private Story story;
private String perspective;
public Long getRelationshipId() {
return relationshipId;
}
public void setRelationshipId(Long relationshipId) {
this.relationshipId = relationshipId;
}
public Being getBeing() {
return being;
}
public void setBeing(Being being) {
this.being = being;
}
public Story getStory() {
return story;
}
public void setStory(Story story) {
this.story = story;
}
public String getPerspective() {
return perspective;
}
public void setPerspective(String perspective) {
this.perspective = perspective;
}
}
从那里我基本上为 spring 数据服务设置了基本类型的存储库剩余资源 类。那些照顾实体,但他们未能真正解决我的关系。做的是实现一个单独的rest route来保存它
BeingController.java:
package com.chronicler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.chronicler.model.Involvement;
import com.chronicler.repo.InvolvementRepository;
@RestController
public class BeingController {
@Autowired
InvolvementRepository involvementRepository;
@RequestMapping(value="/beingStory", method=RequestMethod.POST)
public Involvement createBeingStoryRelationship(@RequestBody Involvement involvement) {
involvementRepository.save(involvement);
return involvement;
}
}
从那里,只需 post 使用以下 json/beingStory json body 即可准确地创建关系:
{
"character": {
"id": 17,
"firstName": "Dr. Victor",
"lastName": "Frankenstein",
"hero": true,
"villain": true
},
"story": {
"id": 15,
"title": "Frankenstein",
"slug": "A doctor plays god"
},
"relationshipId": 10,
"perspective": "I did a monstrous thing. I wanted to create life, but I created horrors... such unimaginable horrors, such that mankind has not ever imagined."
}
从那时起,您就可以了解从人物到故事的关系。将来我将不得不添加更多内容,因为我将通过此示例应用程序进行更多操作以实现反向关系以查看所选故事中的角色参与,并且我打算添加角色之间的关系。
我正在开发一个ui小测试应用程序作为学习 Angular 和在很多 Spring 堆栈上刷新自己的方式。我对 Neo4J 有一些小经验,但应用程序的想法已经有了像 Neo4j 这样的图形数据库。
这个想法非常简单,ui 创建角色和故事,将角色与故事以及彼此联系起来,映射他们各自的故事版本,并创建一些图表来显示角色互动帮助撰写整体叙述。
我已经足够轻松地获得角色和故事的节点,Spring 堆栈非常适合让我轻松地使用节点本身的休息端点。但是我找不到任何创建和维护这些节点之间关系的具体示例。
例如,在 Cypher 中,我可以将一个角色与一个故事联系起来,并将该人物与故事的关系描述为一种关系 属性 与:
match(p:Being ),(s:Story ) where id(p) = 7 and id(s) = 16
create (p)-[r:TOOK_PART_IN{perspective:"I did not know Mr. Grey better than an acquaintance, though I knew others whom did. They were not made better because of their relationship with him."}]->(s) return r
然后使用 Spring 中的映射,我从 REST 端点返回的数据为我提供了我的角色,我可以按照 link 获取该角色所属的故事。我没有看到 post 或从故事中添加或删除角色的方法。
我也只是在 Spring 的文档中找到关于节点的具体示例,而不是 edges/relationships。谁能提供这样的东西?
我完全知道 Neo4J 有它自己的 REST 接口,这基本上也是 Spring 正在使用的。本次练习的主要目的是学习一些新技术(Angular2/typescript)和刷新我对Spring栈的知识
谢谢!
我不确定是否有其他人对此找到了好的或更好的答案,但这是我找到的有效答案。我有一个 spring 引导项目 运行,我将 post 在此答案中提供一些最相关的代码和示例,但要查看整个 REST 服务项目,请检查 https://github.com/jrspriggs/Chronicler
因此,小应用程序的目的 atm 是创建 characters/beings 参与故事,创建故事(具有标题和 slug 线)并创建存在与故事之间的关系存在对与这种关系相关的故事的看法。这样它就收集了每个角色故事的不同版本。
neo4j 实例只是我 Windows 笔记本电脑上 Docker/Kitematic 中的一个基本 neo4j 实例。以下是型号:
Being.java:
package com.chronicler.model;
import java.util.Iterator;
import java.util.Set;
import org.springframework.data.neo4j.annotation.Fetch;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.annotation.RelatedToVia;
@NodeEntity
public class Being {
public Long getId() {
return id;
}
@GraphId private Long id;
private String firstName;
private String lastName;
private boolean hero;
private boolean villain;
@RelatedToVia(type="TOOK_PART_IN")
@Fetch private Set<Involvement> involvements;
public Set<Involvement> getInvolvements() {
return involvements;
}
public void setInvolvements(Set<Involvement> involvements) {
this.involvements = involvements;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public boolean isHero() {
return hero;
}
public void setHero(boolean hero) {
this.hero = hero;
}
public boolean isVillain() {
return villain;
}
public void setVillain(boolean villain) {
this.villain = villain;
}
}
Story.java
package com.chronicler.model;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.NodeEntity;
@NodeEntity
public class Story {
public Long getId() {
return id;
}
@GraphId private Long id;
private String title;
private String slug;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
}
Involvement.java(与故事的关系)
package com.chronicler.model;
import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.Fetch;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.StartNode;
@RelationshipEntity(type="TOOK_PART_IN")
public class Involvement {
@GraphId private Long relationshipId;
@Fetch @StartNode private Being being;
@Fetch @EndNode private Story story;
private String perspective;
public Long getRelationshipId() {
return relationshipId;
}
public void setRelationshipId(Long relationshipId) {
this.relationshipId = relationshipId;
}
public Being getBeing() {
return being;
}
public void setBeing(Being being) {
this.being = being;
}
public Story getStory() {
return story;
}
public void setStory(Story story) {
this.story = story;
}
public String getPerspective() {
return perspective;
}
public void setPerspective(String perspective) {
this.perspective = perspective;
}
}
从那里我基本上为 spring 数据服务设置了基本类型的存储库剩余资源 类。那些照顾实体,但他们未能真正解决我的关系。做的是实现一个单独的rest route来保存它
BeingController.java:
package com.chronicler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.chronicler.model.Involvement;
import com.chronicler.repo.InvolvementRepository;
@RestController
public class BeingController {
@Autowired
InvolvementRepository involvementRepository;
@RequestMapping(value="/beingStory", method=RequestMethod.POST)
public Involvement createBeingStoryRelationship(@RequestBody Involvement involvement) {
involvementRepository.save(involvement);
return involvement;
}
}
从那里,只需 post 使用以下 json/beingStory json body 即可准确地创建关系:
{
"character": {
"id": 17,
"firstName": "Dr. Victor",
"lastName": "Frankenstein",
"hero": true,
"villain": true
},
"story": {
"id": 15,
"title": "Frankenstein",
"slug": "A doctor plays god"
},
"relationshipId": 10,
"perspective": "I did a monstrous thing. I wanted to create life, but I created horrors... such unimaginable horrors, such that mankind has not ever imagined."
}
从那时起,您就可以了解从人物到故事的关系。将来我将不得不添加更多内容,因为我将通过此示例应用程序进行更多操作以实现反向关系以查看所选故事中的角色参与,并且我打算添加角色之间的关系。