Neo4j3.5学习笔记——创建唯一节点
程序员文章站
2022-05-28 20:26:52
...
跟着官网代码学习.jpg–jdk 1.8.0 & neo4j 3.5
https://neo4j.com/docs/java-reference/current/java-embedded/
在许多用例中,实体需要某种程度的唯一性。例如,一个系统中可能只存在一个具有特定电子邮件地址的用户。如果多个并发线程尝试创建用户,则会创建重复的线程。
解决方法1:单线程
只使用一个线程,没有两个线程会同时尝试创建一个特定的实体。在cluster中,外部单线程客户机可以执行这些操作。
解决方法2:uniqueness constraints and MERGE
定义唯一性约束和Cypher的MERGE
是获取或创建唯一节点的最有效方法。
1)创建唯一性约束unique constraint:代码中User是分配给一组节点的标签。当我们创建一个唯一约束时,Neo4j在任意标签内的属性上声明唯一性约束。
private void creatUniqueConstraint() {
try(Transaction tx = graphDb.beginTx()) {
graphDb.schema().constraintFor(Label.label("User"))
.assertPropertyIsUnique("name")
.create();
tx.success();
}
}
- 要在Cypher中执行此操作,它看起来像这样:
CREATE CONSTRAINT ON (user:User) ASSERT user.name IS UNIQUE
2)使用MERGE
创建唯一节点
private Node createUniqueNode(String username) {
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 = graphDb.execute( queryString, parameters ).columnAs( "n" );
result = resultIterator.next();
tx.success();
return result;
}
- 第4行创建了查询字符串:
MERGE (n:User {name: {name}}) RETURN n
,这意味着我们希望MATCH
或CREATE
具有任意名称的用户,该名称作为参数{name}
提供,而该参数由第5行名为parameters的哈希映射提供。哈希映射充当我们的参数的简单键-值列表,其中键必须与Cypher查询中提供的参数匹配,在本例中参数为{name}
。
resultIterator = engine.execute( queryString, parameters ).columnAs( "n" );
-
然后通过提供查询字符串来执行事务,该字符串包含带有声明参数占位符的Cypher语句,以及包含键-值列表的参数映射。
-
对哈希的插入失败(不唯一)则尝试失败,如果是这样的话,为什么要加上uniqueness constraint?
---- 由于MERGE
子句获取或创建(如果记录不存在,则创建),在此上下文中无法触发唯一性约束。
---- 但是唯一性约束对于CREATE
和SET
语句是有约束力的:使用CREATE
语句创建具有重复name属性的节点,事务将失败;尝试SET
另一个节点的name属性为重复的也会失败。
3. 具体代码见: https://github.com/Amy996bbq/Neo4j/blob/master/learn/UniquenessNode.java