使用spring数据neo4j更新关系属性

时间:2016-09-28 22:13:28

标签: java neo4j spring-data-neo4j

我目前正致力于创建一个使用neo4j存储每个网页内容的网络抓取工具。除了存储内容外,neo4j还用于存储页面之间的链接,稍后将用于计算页面排名。

我正在使用spring-data-neo4j 4.1.12.RELEASE,当我尝试更新两个节点之间的关系时遇到了问题。这是所有相关的代码。

网页(节点)

@NodeEntity
public class WebPage {
    @GraphId 
    private Long nodeId;

    private String url;

    @Relationship(type = "LINKED_TO", direction = Relationship.OUTGOING)
    private Set<Link> outgoingLinks = new HashSet<>();

    public WebPage() {}

    public String getUrl() {
        return url;
    }

    public WebPage setUrl(String url) {
        this.url = url;
        return this;
    }

    @Relationship(type = "LINKED_TO", direction = Relationship.OUTGOING)
    public Set<Link> getOutgoingLinks() {
        return outgoingLinks;
    }

    @Relationship(type = "LINKED_TO", direction = Relationship.OUTGOING)
    public void setOutgoingLinks(Set<Link> outgoingLinks) {
        this.outgoingLinks = outgoingLinks;
    }


    public void addOutgoingLink(WebPage linkedWebPage, String anchor) {
        Link outgoingLink = new Link(this, linkedWebPage, anchor);
        outgoingLinks.remove(outgoingLink);
        outgoingLinks.add(outgoingLink);
    }
}

链接(关系)

@RelationshipEntity(type = "LINKED_TO")
public class Link {
    @GraphId
    Long id;

    @StartNode
    private WebPage sourceWebPage;
    @EndNode
    private WebPage linkWebPage;

    @Property
    private String anchor;

    public Link() {}

    public Link(WebPage sourceWebPage, WebPage linkWebPage, String anchor) {
        this.sourceWebPage = sourceWebPage;
        this.linkWebPage = linkWebPage;
        this.anchor = anchor;
    }    

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((linkWebPage == null) ? 0 : linkWebPage.hashCode());
        result = prime * result + ((sourceWebPage == null) ? 0 : sourceWebPage.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Link other = (Link) obj;
        if (linkWebPage == null) {
            if (other.linkWebPage != null)
                return false;
        } else if (!linkWebPage.equals(other.linkWebPage))
            return false;
        if (sourceWebPage == null) {
            if (other.sourceWebPage != null)
                return false;
        } else if (!sourceWebPage.equals(other.sourceWebPage))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Link [sourceWebPage=" + sourceWebPage + ", linkWebPage=" + linkWebPage
                        + ", anchor=" + anchor + "]";
    }

}

存储库

@Repository
public interface WebPageRepository extends GraphRepository<WebPage>{
    WebPage findByUrl(@Param("url") String url);
}

测试

@Test
public void test() {
    WebPage sourceWebPage = webPageRepository.findByUrl("http://www.test.com/");
    if (sourceWebPage == null) {
        sourceWebPage = new WebPage().setUrl("http://www.test.com/");
    }
    WebPage linkedWebPage = webPageRepository.findByUrl("http://www.example.com/");
    if (linkedWebPage == null) {
        linkedWebPage = new WebPage().setUrl("http://www.example.com/");
    }

    String anchor = "test";
    sourceWebPage.addOutgoingLink(linkedWebPage, anchor);
    webPageRepository.save(sourceWebPage); 
}

注意

在链接域上覆盖了equals和hashCode,因此它只使用源WebPage和链接WebPage来确定相等性。我这样做是因为我不想在两个WebPages之间创建多个链接。因此,如果WebPage具有到另一个WebPage的多个链接,则所有锚点都在一个链接下收集。

问题

在测试中,我创建/找到两个WebPages,然后创建/更新两者之间的链接。以下是我用来更新链接的相关代码(来自上方)。

public void addOutgoingLink(WebPage linkedWebPage, String anchor) {
    Link outgoingLink = new Link(this, linkedWebPage, anchor);
    outgoingLinks.remove(outgoingLink);
    outgoingLinks.add(outgoingLink);
}

问题是关系将在第一次测试时创建,但在第二次测试时删除。此创建和删除周期将无限期地继续。

这是一个运行示例,从数据库中没有数据开始。

运行#1

Run #1

运行#2

Run #2

运行#3,与#1相同

运行#4,与#2相同

有更好的方式来更新关系吗?从我的阅读来看,似乎更喜欢通过NodeEntity更新关系,因为使用@Query语法会导致数据同步问题。

非常感谢任何有关此问题的帮助。

谢谢!

马特

0 个答案:

没有答案