java Neo4j 在创建之前检查节点是否存在?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10999730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Neo4j check if node exists before creating?
提问by Tom Carrick
I have a feeling I'm going about this all wrong. But anyway.
我有一种感觉,我在做这一切都是错误的。但无论如何。
I have an sql database which has essentially a purposefully denormalised table which I've constructed to make this task easier for me, so I can just grab stuff from one table.
我有一个 sql 数据库,它本质上有一个故意非规范化的表,我构建它是为了让我更轻松地完成这项任务,所以我可以从一个表中获取内容。
What I have is a table of pairs, something like this:
我有一个成对表,如下所示:
user_lo | user_hi | something_else | other stuff
1000 | 1234 | 1231251654 | 123
1050 | 1100 | 1564654 | 45648
1080 | 1234 | 456444894648 | 1
And so on.
等等。
So for my neo4j graph db, I want each user id as a node, the other stuff isn't too important but will be the stuff in the relations basically.
所以对于我的 Neo4j 图数据库,我希望每个用户 ID 作为一个节点,其他的东西不是太重要,但基本上是关系中的东西。
I only want one node for each user, so my feeling is that if I do something like this:
我只想要每个用户一个节点,所以我的感觉是,如果我做这样的事情:
while (rs.next()) {
node_lo = db.createNode();
node_lo.setProperty("user_id", rs.getInt(1));
node_hi = db.createNode();
node_hi.setProperty("user_id", rs.getInt(2));
}
That when we add the node with user_id 1234 for the second time, it will just create a new node, but I what I want is for it to just grab this node instead of creating it so I can add it to the relationship to 1080 in this case.
当我们第二次添加 user_id 为 1234 的节点时,它只会创建一个新节点,但我想要的是它只是抓取这个节点而不是创建它,这样我就可以将它添加到 1080 的关系中这个案例。
So what is the way to do this?
那么有什么方法可以做到这一点呢?
采纳答案by Andres
Have you looked at CREATE UNIQUE?
你看过CREATE UNIQUE吗?
If you can't use Cypher, maybe you can use unique nodes?
如果您不能使用 Cypher,也许您可以使用唯一节点?
回答by Nicholas
Use an index to search, and if no result of found, create a new one.
使用索引进行搜索,如果没有找到结果,则创建一个新的。
Index<Node> userIndex = graphDatabaseService.index().forNodes('UserNodes');
IndexHits<Node> userNodes = userIndex.get('id', 1234);
if(!userNodes.hasNext()){
//Create new User node
} else {
Node userNode = userNodes.next();
}
Is this the type of operation you are looking for?
这是您正在寻找的操作类型吗?
回答by Michael Hunger
You'll probably want to use the UniqueNodeFactoryprovided by Neo4j.
您可能想要使用Neo4j 提供的UniqueNodeFactory。
public Node getOrCreateUserWithUniqueFactory( String username, GraphDatabaseService graphDb )
{
UniqueFactory<Node> factory = new UniqueFactory.UniqueNodeFactory( graphDb, "UserNodes" )
{
@Override
protected void initialize( Node created, Map<String, Object> properties )
{
created.setProperty( "id", properties.get( "id" ) );
}
};
return factory.getOrCreate( "id", id );
}
回答by Shannon Monasco
Normalize your SQL tables to look like nodes and relationships. Then with cypher in your migration you can make the migration rerunnable by something like
规范您的 SQL 表,使其看起来像节点和关系。然后在迁移中使用密码,您可以通过类似的方式使迁移重新运行
start a = node:node_auto_index('id:"<PK_Value>"')
delete a
create a = {id: "<PK_VALUE>", etc}
for nodes and since you should have in your many-to-many middle table:
对于节点,因为你应该在你的多对多中间表中:
start LHS = node:node_auto_index('id:"<LHS_PK>"'),
RHS = node:node_auto_index('id:"<RHS_PK>"')
create unique LHS=[:<relType> {<rel props>}]->RHS
now you will end up with no duplicates and can rerun as much as you like.
现在您将不再有重复项,并且可以随心所欲地重新运行。
回答by Wesam Na
use this function: where: ID is the key which you want to check if already exist Type: is the type of the node ( the label) this function will create the node and return it, then you can add more properties.
使用这个函数: 其中: ID 是要检查是否已存在的键 Type: 是节点的类型(标签) 此函数将创建节点并返回它,然后您可以添加更多属性。
public static Node getOrCreateUserWithUniqueFactory( long ID, GraphDatabaseService graphDb, String Type )
{
UniqueFactory<Node> factory = new UniqueFactory.UniqueNodeFactory( graphDb, Type )
{
@Override
protected void initialize( Node created, Map<String, Object> properties )
{
created.addLabel( DynamicLabel.label( Type ) );
created.setProperty( "ID", properties.get( "ID" ) );
}
};
return factory.getOrCreate( "ID", ID );
}
回答by Burhan
using cypher query, you can create a unique node with the following syntax,
使用密码查询,您可以使用以下语法创建一个唯一的节点,
CYPHER 2.0 merge (x:node_auto_index{id:1})
when making a REST call, one can make batch insertion like
在进行 REST 调用时,可以进行批量插入,例如
$lsNodes[] = array(
'method'=> 'POST', 'to'=> '/cypher',
'body' => array(
'query' => 'CYPHER 2.0 merge (x:node_auto_index{id_item:{id}})',
'params' => array('id'=>1)
),
'id'=>0
);
$sData = json_encode($lsNodes);
similarly for creating relationships in a batch request, do the following
类似地在批处理请求中创建关系,请执行以下操作
$lsNodes[] = array(
'method'=> 'POST', 'to'=> '/cypher',
'body' => array(
'query' => 'start a=node:node_auto_index(id={id1}), b = node:node_auto_index(id={id2}) create unique a-[:have{property:30}}]-b;',
'params' => array(
'id1' => 1, 'id2'=> 2
)
),
'id' => 0
);
$sData = json_encode($lsNodes);