Spring Data REST Neo4j 创建关系

Posted

技术标签:

【中文标题】Spring Data REST Neo4j 创建关系【英文标题】:Spring Data REST Neo4j create a relationship 【发布时间】:2016-11-29 00:15:27 【问题描述】:

我正在构建一个小测试应用程序,以此来学习 Angular 并在很多 Spring 堆栈上刷新自己。我对 Neo4J 有一些小的经验,但是这个应用程序的想法是基于 Neo4j 之类的图形数据库。

这个想法非常简单,一个用于创建角色和故事的用户界面,并将角色与故事以及彼此相关联,映射他们各自版本的故事并创建一些图表来显示角色交互以帮助编写整体叙事.

我已经很容易地为角色和故事获得了节点,并且 Spring 堆栈非常适合让我休息,易于使用节点本身的休息端点。但是我找不到任何创建和维护这些节点之间关系的具体示例。

例如,在 Cypher 中,我可以将一个角色与一个故事联系起来,并将该人物与故事的关系作为一种关系属性来讲述:

match(p:Being ),(s:Story ) where id(p) = 7 and id(s) = 16 create (p)-[r:TOOK_PART_INperspective:"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 端点返回的数据为我提供了我的角色,我可以通过链接获取该角色所属的故事。我没有看到一种方法来发布或添加从故事中添加或删除角色。

我也只在 Spring 的文档中找到关于节点的具体示例,而不是真正的边缘/关系。任何人都可以提供这样的东西吗?

我完全知道 Neo4J 有它自己的 REST 接口,这基本上也是 Spring 所消耗的。本练习的主要目的是学习一些新技术(Angular2/typescript)并刷新我对 Spring 堆栈的知识

谢谢!

【问题讨论】:

假设您正在寻找有关使用 Spring Data Neo4j 创建/修改关系的文档,您是否看过 docs.spring.io/spring-data/neo4j/docs/current/reference/html 【参考方案1】:

我不确定其他人是否曾经找到一个好的或更好的答案,但这是我发现的工作。我有一个 spring boot 项目正在运行,我将在这个答案中发布一些最相关的代码和示例,但是要查看整个 REST 服务项目,请查看https://github.com/jrspriggs/Chronicler

因此,小应用程序的目的是创建参与故事的角色/存在,创建故事(具有标题和主线)并在存在的角度创建存在与故事之间的关系与这种关系相关的故事。通过这种方式,它收集了每个角色的不同版本的故事。

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 数据服务设置了基本类型的存储库休息资源类。那些照顾实体,但他们未能真正为我解决关系。什么是实现一个单独的休息路线来保存它

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 即可准确地创建关系:


    "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."

从那时起,您可以将关系从人物转移到故事。将来我将不得不添加更多内容,因为我通过这个示例应用程序来实现反向关系,以便从选定的故事中查看角色参与,并且我打算添加角色之间的关系。

【讨论】:

以上是关于Spring Data REST Neo4j 创建关系的主要内容,如果未能解决你的问题,请参考以下文章

IgnoreCase Finder 不适用于 Spring Data Rest 和 Neo4J

Spring Data Neo4j 多态关联出现嵌入

使用 REST 访问 Neo4j 数据

使用 Spring Boot 和 Neo4j 通过 REST API 插入实体时出错

如何在 Grails 2.4.2 项目中集成 Spring Data Neo4j 和 Mongodb

Spring Neo4j:无法使用id保存节点