问题描述
我正在构建一个小的测试应用程序,以学习Angular并在许多Spring堆栈中使自己振作起来.我对Neo4J有一些次要的经验,但是应用程序的想法已经有了Neo4j之类的图形数据库.
I'm building a little test app as a way to learn Angular and refresh myself on a lot of the Spring stack. I have some minor experience with Neo4J, but the app idea has ground with a graph db like Neo4j.
这个想法非常简单,它是一个用于创建角色和故事并将角色与故事相互关联,映射故事的各个版本并创建一些图形来显示角色互动的用户界面,以帮助编写整体叙述
The idea is pretty simple, a ui to create characters and stories, and relate the characters to the stories and each other, map their individual versions of a story and create some graphs that show the character interactions to help write the overall narrative.
我已经足够容易地获得角色和故事的节点,并且Spring堆栈非常适合让我轻松使用节点本身的rest终结点.但是我找不到在这些节点之间创建和维护关系的任何具体示例.
I've got nodes for the characters and stories easily enough and the Spring stack is great for giving me rest easy to use rest endpoints for the nodes themselves. But I can't find any concrete examples of creating and maintaining the relationships between those nodes.
例如,在Cypher中,我可以将角色与故事相关联,并通过以下内容将其与故事的关联作为关系属性:
For instance, in Cypher, I can relate a character to a story and tell that being's involvement to the story as a relationship property with:
match(p:Being ),(s:Story ) where id(p) = 7 and id(s) = 16create (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
match(p:Being ),(s:Story ) where id(p) = 7 and id(s) = 16create (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端点获取的数据给了我角色,我可以通过链接获取角色所参与的故事.我看不到发布或添加故事中人物的方法.
Then with the mapping in Spring, the data I get back from the REST endpoint gives me my character and I can follow a link to get the stories that character is a part of. I don't see a way though to post or put to add or remove the character from stories.
我也只能在Spring的文档中找到有关节点的具体示例,而不是真正的边/关系.谁能提供类似的东西?
I'm also only finding concrete examples in docs from Spring regarding nodes, not really with edges/relationships. Can anyone supply anything like that?
我完全意识到Neo4J有它自己的REST接口,这基本上也是Spring所消耗的.本练习的主要目的是学习一些新技术(Angular2/typescript)并刷新我对Spring堆栈的了解
I am fully aware that Neo4J has it's own REST interface, and that is basically what Spring is consuming as well. The main purpose of this exercise is learning some new technology (Angular2/typescript) and refreshing my knowledge of the Spring stack
谢谢!
推荐答案
我不确定是否有人找到了更好或更好的答案,但这就是我发现的有效方法.我正在运行一个Spring Boot项目,我将在此答案中发布一些最相关的代码和示例,但是要查看整个REST服务项目,请检查 https://github.com/jrspriggs/Chronicler
I'm not sure if anyone else has ever found a good or better answer to this, but here is what I had found to work. I have a spring boot project running, I'll post some of the most pertinent code and examples in this answer, but to see the whole REST service project, check https://github.com/jrspriggs/Chronicler
因此,小型应用程序的自动取款机的目的是创建参与故事的角色/事物,创建故事(以标题和子弹线为特征),并以存在者的视角在存在者和故事之间建立关系那种关系的故事.这样,它可以从每个角色收集故事的不同版本.
So, the purpose atm for the small app is to create characters/beings that take part in stories, create stories (featuring a title and slug line) and create a relationship between a being and a story with the being's perspective of the story attached to that relationship. This way it collects the various versions of the story from each character.
neo4j实例只是Windows笔记本电脑上Docker/Kitematic中的一个基本neo4j实例.这是模型:
The neo4j instance is just a basic neo4j instance in Docker/Kitematic on my Windows laptop. Here are the models:
Being.java:
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
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(与故事之间的关系)
Involvement.java (relationship between being to story)
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数据服务设置了基本的存储库其余资源类.这些人照顾实体,但他们没有真正为我解决这种关系.要做的是实现一条单独的休息路线来保存它
From there I have basically the base kind of repository rest resource classes set up for the spring data services. Those take care of the entities, but they fail to really address the relationship for me. What does is to implement a separate rest route to save it
BeingController.java:
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;
}
}
从那里,只需使用以下json主体将其发布到localhost:3000/beingStory即可准确创建关系:
From there, just posting to localhost:3000/beingStory with the following kind of json body will accurately create the relationship:
{
"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."
}
从那时起,您可以将人与故事之间的关系进行分析.将来,我将在本示例应用程序中进行更多工作,以实现反向关系以从选定的故事中查看角色的参与,因此我将不得不添加更多角色,并且打算在角色之间添加关系.
From that point then, you can walk the relationships from the person to the story. I'll have to add more in the future as I work through this sample app some more to implement the reverse relationship for seeing character involvements from a selected story, and I intend to add relationships between the characters.
这篇关于Spring Data REST Neo4j创建关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!