Neo4j SDN4和内部ID的正确用法

时间:2017-02-13 19:11:02

标签: neo4j spring-data-neo4j-4 neo4j-ogm

我读到使用Neo4j内部ID作为外部目的并不是一个好习惯。

我认为我在SDN4 / Neo4j应用程序中犯了一个错误,因为我在任何地方都使用内部ID。

我的应用程序中的每个SDN 4节点实体都具有以下属性:

@GraphId
private Long id;

我将此长值用作我的Web应用程序URL的一部分...例如

/products/3245234

其中3245234是此产品节点实体的内部Neo4j标识符。

从Neo4j的角度来看是否安全 - 以这种方式使用内部ID?如果不是,请举例说明新的代理键如何解决这个问题。

2 个答案:

答案 0 :(得分:5)

在谈到Neo4j内部ID如何被回收时,Eric所说的是正确的。

我们已开始增加对SDN的支持,以帮助开发人员解决这个问题。我们可以通过几个例子来做到这一点。

示例1:当您拥有自然ID

假设我们有一个User域对象,它可以通过名为email的字段进行唯一标识。我们可能会这样设置我们的模型:

@NodeEntity
public class User {

    @GraphId
    private Long id;

    @Index(unique=true, primary=true)
    private String email;

    ... 

}

然后我们可以设置一个存储库:

public interface UserRepository extends CrudRepository<User, String> {

}

注意参数化类型中的最后一个值是String。这表示此类使用的主要索引。

您现在可以执行以下操作:

User user = userRepository.findOne("john.doe@email.com");

了解如何传递班级的主要ID?

示例2:当您需要合成ID

假设我们上面定义的用户有推文。由于推文没有自然ID,我们给它一个。避免ID冲突的最佳方法是使用类型4 UUID。幸运的是,Java预装了UUID,SDN支持它的持久性。

import org.neo4j.ogm.annotation.typeconversion.Convert;
import org.neo4j.ogm.typeconversion.UuidStringConverter;
import java.util.UUID;

@NodeEntity
public class Tweet {

    @GraphId
    private Long id;

    @Convert(UuidStringConverter.class)
    @Index(unique = true, primary = true)
    private UUID uuid;

    ...

    public Tweet(String message) {
        this.uuid = UUID.randomUUID();
        // other initialisation.
    }
}

所以我们这里有一个UUID分配给任何创建的推文。然后可以通过转换器将其保存到数据库中。关于这一点的一个方便的事情是没有额外的库可以安装。它也保证(好吧,大部分!)永远不会有内部Neo4j ID的问题。专业人士(或者说)是由您的应用程序代码制作的ID是普遍唯一的。

如果您希望数据库始终生成UUID,那么我还会推荐GraphAware https://github.com/graphaware/neo4j-uuid插件。

Tweet Repository再次利用了这一点:

public interface TweetRepository extends CrudRepository<Tweet, UUID> {

}

您现在可以执行以下操作:

Tweet tweet = tweetRepository.findOne(UUID.fromString("0f6e7004-cefc-4397-b4d2-078c1370856a"));

最后一点;在撰写本文时@Indexed(unique=true,primary=true)可能会更改为在SDN 5.0中简称为@Id

答案 1 :(得分:4)

从应用程序视图中,使用Neo4j内部标识是安全的,因为应用程序中的任何内容都不会因使用它们而中断。

也就是说,Neo4j内部id被循环使用,我的意思是,如果节点或关系的内部id为12345,并且在某些时候删除了节点或关系,则12345的id有资格被未来的节点重用或关系。我认为明智地假设新的id将在未来的某个时候重用。这具有负面影响,即Neo4j内部id不被认为是“稳定的”,不应在您的应用程序之外使用。

至于一个新的代理键的例子,我会指向GraphAware的https://github.com/graphaware/neo4j-uuid的neo4j-uuid项目。此Neo4j插件可用于在所有节点和关系上自动创建唯一且稳定的UUID,这些UUID将不会也不会被更改或更新。