Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何仅在neo4j中不存在节点时创建新节点_Java_Neo4j_Spring Data Neo4j - Fatal编程技术网

Java 如何仅在neo4j中不存在节点时创建新节点

Java 如何仅在neo4j中不存在节点时创建新节点,java,neo4j,spring-data-neo4j,Java,Neo4j,Spring Data Neo4j,我正在使用neo4j和vertx 我使用的是Neo4jJDBC 我设法创建了用户,但我如何“升级”此查询以创建新用户(具有唯一索引),前提是该用户不存在。 用户ID应该是主键 private final Logger logger = Logger.getLogger(Neo4jRepo.class); private Connection conn = null; public Neo4jRepo() { logger.debug("Neo4jRepo, I

我正在使用neo4j和vertx

我使用的是Neo4jJDBC

我设法创建了用户,但我如何“升级”此查询以创建新用户(具有唯一索引),前提是该用户不存在。 用户ID应该是主键

 private final Logger logger = Logger.getLogger(Neo4jRepo.class);
    private Connection conn = null;

    public Neo4jRepo() {
        logger.debug("Neo4jRepo, Init");
        try {
            Class.forName("org.neo4j.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:neo4j://localhost:7474/");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);

        }
    }
..
public boolean addDistanceUserListByForUserId(String userId) {
        try {
            final PreparedStatement ps = conn.prepareStatement( "create (n:User {name:{1}})" );
            ps.setString( 1, "userId" );
            ps.execute();

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return true;
    }
谢谢,,
光线。

使用
合并
而不是
创建

"MERGE (n:User {name:{1}})"
[更新1]

以下示例说明如何修改
addDistanceUserListByForUserId()
,以便返回包含已创建/现有
用户的属性的
映射

public Map<String, Object> addDistanceUserListByForUserId(String userId) {
    try {
        final PreparedStatement ps = conn.prepareStatement(
            "MERGE (n:User {name:{1}}) RETURN n" );
        ps.setString( 1, "userId" );
        ResultSet rs = ps.executeQuery();
        if (rs.next()) {
            return (Map<String, Object>) rs.getObject("n");
        }
    } catch (SQLException e) { 
        throw new RuntimeException(e);
    } 
    return null; 
}
以下是对该查询的解释:

  • 它使用
    可选匹配
    ,因此如果未找到具有指定的
    名称
    用户
    ,则不会跳过查询的其余部分(但
    n
    将为
    NULL
  • 然后创建一个
    todo
    集合,告诉
    FOREACH
    子句是否应该创建新的
    User
    节点。如果
    todo
    集合为空,
    FOREACH
    子句不执行任何操作
  • 在修改子句(如
    FOREACH
    )和后续的
    MATCH
    子句之间需要有一个
    WITH
    子句。我们实际上不需要向前传递任何东西,所以我们只需要使用
    todo
    ,因为我们已经有了它
  • 我们需要另一个
    MATCH
    查询,因为我们希望返回找到的节点或刚刚创建的节点。但是,除非我们进行另一次
    匹配,否则无法获取由
    FOREACH
    创建的节点

您应该使用
MERGE
而不是
CREATE
。如果节点不存在,这将创建节点。如果节点已经存在,则
合并
将像正常的
匹配
操作一样工作

重要提示:
{}
属性语法中,应仅使用具有唯一约束的属性。Neo4j将合并
{}
中具有相同属性的节点

如果合并后要在节点上设置其他数据,则:

合并(用户:用户{name:“John”,年龄:20})
-错误的方式。因为数据库中没有具有此类
名称
年龄
属性组合的节点,数据库将尝试创建该节点。这将导致
约束冲突
,因为这样的
名称
已经存在

正确版本:

MERGE (user:User {name: "John"}) 
SET user.age = 20

此版本将首先搜索节点(并在需要时创建),然后才在该节点上设置属性。

如果您使用neo4J作为本地主机,则应注意neo4J embedded,因为它作为外部服务的性能更好。我们考虑将其嵌入。但是我们失去了GUI和其他东西。你认为嵌入式比ext好吗?嵌入式比fi好你在同一台服务器上:)可以使用嵌入式检索GUI:)如果我在进行远程操作,如何使用jdbc连接器按Id获取节点?知道如何映射它吗?永远不要使用nodeId作为数据,您应该添加自己的id属性,并使用约束将其设置为唯一。否则,您可以使用cypher(start n=node())通过其ID检索节点。请参阅我的更新答案。我还没有测试过该代码,但它似乎应该可以工作。这可以工作,但我对name使用了唯一的约束,并且我还有另一个名为age的属性。所以,如果用户已经存在,但具有不同的名称,并且我尝试合并,则会出现以下异常:执行cypher语句时出错[{code=Neo.ClientError.Schema.ConstraintViolation,message=Node 15已经存在,标签为user,属性为“name”=[Jossef]}]我已经更新了我的答案,并提出了一个建议,希望您能够解决您的约束问题。
MERGE (user:User {name: "John"}) 
SET user.age = 20