如何在neo4j中创建唯一的节点?

时间:2014-03-09 00:27:22

标签: neo4j

我想确保我不使用neo4j数据库创建多个节点。我看到here这是首选方法(即使在查看此page之后),但我不明白代码在该示例中的实际操作。有人可以详细说明外行/诺布吗?

文字代码是:

  

创建Cypher执行引擎和唯一约束。

try ( Transaction tx = graphdb.beginTx() )
{
    graphdb.schema()
            .constraintFor( DynamicLabel.label( "User" ) )
            .assertPropertyIsUnique( "name" )
            .create();
    tx.success();
}

return new ExecutionEngine( graphdb() );
  

使用MERGE创建唯一节点。

Node result = null;
ResourceIterator<Node> resultIterator = null;
try ( Transaction tx = graphDb.beginTx() )
{
    String queryString = "MERGE (n:User {name: {name}}) RETURN n";
    Map<String, Object> parameters = new HashMap<>();
    parameters.put( "name", username );
    resultIterator = engine.execute( queryString, parameters ).columnAs( "n" );
    result = resultIterator.next();
    tx.success();
    return result;
}

1 个答案:

答案 0 :(得分:6)

  

代码似乎正在创建Cypher的约束   用户和名称必须是唯一的,对吗?

在此示例中创建约束的代码在Java API for Neo4j中进行管理。标签将节点组合在一起,任何节点都可以有多个标签。请参阅此处以了解有关标签的更多信息:

http://docs.neo4j.org/chunked/milestone/graphdb-neo4j-labels.html

在这种情况下,User是分配给图中一组节点的标签。当我们创建一个唯一约束时,我们告诉Neo4j在任意标签内的属性上声明唯一性约束。

这是在本声明中管理的:

graphdb.schema()
        .constraintFor( DynamicLabel.label( "User" ) )
        .assertPropertyIsUnique( "name" )
        .create();
tx.success();

要在Cypher中执行此操作,它看起来像这样:

CREATE CONSTRAINT ON (user:User) ASSERT user.name IS UNIQUE

请参阅此处以了解有关Neo4j 2.0可选架构的更多信息:

http://docs.neo4j.org/chunked/milestone/query-constraints.html

  

如果是这样,他们为什么要把东西存放在哈希?

在第二块代码中,为了便于参考,我将其复制到这里:

Node result = null;
ResourceIterator<Node> resultIterator = null;
try ( Transaction tx = graphDb.beginTx() )
{
    String queryString = "MERGE (n:User {name: {name}}) RETURN n";
    Map<String, Object> parameters = new HashMap<>();
    parameters.put( "name", username );
    resultIterator = engine.execute( queryString, parameters ).columnAs( "n" );
    result = resultIterator.next();
    tx.success();
    return result;
}

我们正在事务上下文中包装托管调用。在第4行,我们创建了查询字符串:MERGE (n:User {name: {name}}) RETURN n,这意味着我们希望MATCHCREATE具有任意名称的用户。该名称作为参数{name}提供,该参数在以下行中名为parameters的哈希映射中提供。哈希映射充当我们的参数的简单键/值列表,其中键必须与Cypher查询中提供的参数匹配,在本例中为{name}

resultIterator = engine.execute( queryString, parameters ).columnAs( "n" );

然后通过提供查询字符串来执行事务,该字符串包含带有声明参数占位符的Cypher语句,以及包含键/值列表的参数映射。

  

如果对哈希的插入失败(不唯一),则尝试失败?如果是这样的话,为什么要加上约束?

由于MERGE子句获取或创建(如果记录不存在,则创建),在此上下文中无法触发唯一性约束。如果您尝试使用CREATE语句创建具有重复name属性的节点,则事务将失败。如果您尝试SET具有name标签的节点集中具有重复User属性的另一个节点上的{{1}}名称属性,情况也是如此。