8

我有一种感觉,这一切都错了。但不管怎么说。

我有一个 sql 数据库,它本质上是一个有目的的非规范化表,我构建它是为了让这个任务对我来说更容易,所以我可以从一个表中获取内容。

我所拥有的是一对表,如下所示:

user_lo | user_hi | something_else | other stuff
1000    | 1234    | 1231251654     | 123
1050    | 1100    | 1564654        | 45648
1080    | 1234    | 456444894648   | 1

等等。

所以对于我的 neo4j 图形数据库,我希望每个用户 id 作为一个节点,其他的东西不太重要,但基本上是关系中的东西。

我只希望每个用户有一个节点,所以我的感觉是,如果我做这样的事情:

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));
}

当我们第二次添加 user_id 为 1234 的节点时,它只会创建一个新节点,但我想要的是它只是抓住这个节点而不是创建它,这样我就可以将它添加到 1080 的关系中这个案例。

那么这样做的方法是什么?

4

6 回答 6

4

你看过CREATE UNIQUE吗?

如果您不能使用 Cypher,也许您可​​以使用唯一节点

于 2012-06-12T15:40:05.900 回答
4

使用索引搜索,如果没有找到,则创建一个新的。

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();
}

这是您正在寻找的操作类型吗?

于 2012-06-13T02:44:48.810 回答
2

您可能希望使用 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 );
}
于 2012-06-13T22:24:18.957 回答
1

规范化您的 SQL 表,使其看起来像节点和关系。然后在您的迁移中使用密码,您可以通过类似的方式使迁移重新运行

start a = node:node_auto_index('id:"<PK_Value>"')
delete a

create a = {id: "<PK_VALUE>", etc}

对于节点,因为你应该在你的多对多中间表中:

start LHS = node:node_auto_index('id:"<LHS_PK>"'),
      RHS = node:node_auto_index('id:"<RHS_PK>"')
create unique LHS=[:<relType> {<rel props>}]->RHS

现在您最终将没有重复,并且可以根据需要重新运行。

于 2013-04-12T13:30:33.003 回答
1

使用此函数: 其中:ID 是您要检查是否已存在的键类型:是节点的类型(标签)此函数将创建节点并返回它,然后您可以添加更多属性。

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 );
}
于 2015-06-06T16:20:35.310 回答
0

使用密码查询,您可以使用以下语法创建唯一节点,

CYPHER 2.0 merge (x:node_auto_index{id:1})

在进行 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);

类似地,对于在批处理请求中创建关系,请执行以下操作

$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);
于 2013-06-14T15:03:40.787 回答