2012-06-12 26 views
6

Tôi có cảm giác mình sắp sửa sai về điều này. Nhưng dù sao.Neo4j kiểm tra xem nút có tồn tại trước khi tạo không?

Tôi có một cơ sở dữ liệu sql mà về cơ bản là một bảng được chuẩn hóa một cách có chủ đích mà tôi đã xây dựng để làm nhiệm vụ này dễ dàng hơn cho tôi, vì vậy tôi có thể lấy nội dung từ một bảng.

gì tôi có là một bảng các cặp, một cái gì đó như thế này:

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

Và vân vân.

Vì vậy, đối với đồ thị neo4j của tôi db, tôi muốn mỗi id người dùng là nút, các thứ khác không quá quan trọng nhưng sẽ là công cụ trong quan hệ cơ bản.

Tôi chỉ muốn một nút cho mỗi người dùng, vì vậy cảm giác của tôi là nếu tôi làm điều gì đó như thế này:

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

đó khi chúng ta thêm nút với user_id 1234 cho lần thứ hai, nó sẽ chỉ tạo một nút mới, nhưng những gì tôi muốn là chỉ lấy nút này thay vì tạo nó để tôi có thể thêm nó vào mối quan hệ với 1080 trong trường hợp này.

Vậy cách để làm điều này là gì?

Trả lời

2

Bạn đã xem CREATE UNIQUE chưa?

Nếu bạn không thể sử dụng Cypher, có thể bạn có thể sử dụng unique nodes?

+0

lấy hoặc tạo nhà máy hoạt động tốt, cảm ơn. –

4

Sử dụng chỉ mục để tìm kiếm và nếu không tìm thấy kết quả nào, hãy tạo một chỉ mục mới.

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

Đây có phải là loại hoạt động bạn đang tìm kiếm không?

+0

Điều đó có thể hoạt động. Đây có phải là nhanh hơn hoặc chậm hơn hoặc giống như phương thức get hoặc ccreate được liên kết bởi Andres không? Nó trông giống như họ loại làm điều tương tự theo những cách khác nhau, nhưng tôi không thực sự hiểu làm thế nào chỉ số làm việc trong neo4j được nêu ra. –

+0

Tôi tưởng tượng rằng việc lập chỉ mục sẽ nhanh hơn, vì việc lập chỉ mục thường có nghĩa là tra cứu nhanh. – Nicholas

+0

Tôi không biết liệu tôi có đọc tài liệu sai hay không, nhưng không nhận hoặc tạo sử dụng chỉ mục? Tôi bối rối. –

2

Có thể bạn sẽ muốn sử dụng số UniqueNodeFactory do Neo4j cung cấp.

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

Bình thường hóa các bảng SQL của bạn trông giống như các nút và mối quan hệ. Sau đó, với cypher trong việc di chuyển của bạn, bạn có thể làm cho rerunnable di cư bởi một cái gì đó giống như

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

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

cho các nút và kể từ khi bạn nên có trong nhiều-nhiều bảng giữa của bạn:

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

bây giờ bạn sẽ kết thúc không có bản sao và có thể chạy lại nhiều như bạn muốn.

0

sử dụng truy vấn cypher, bạn có thể tạo một nút độc đáo với cú pháp sau,

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

khi thực hiện cuộc gọi REST, người ta có thể thực hiện chèn hàng loạt như

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

tương tự để tạo mối quan hệ trong yêu cầu hàng loạt, hãy thực hiện theo các bước sau

$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); 
1

sử dụng chức năng này: trong đó: ID là khóa mà bạn muốn kiểm tra nếu đã tồn tại Loại: là loại nút (nhãn) chức năng này sẽ tạo nút và trả về, sau đó bạn có thể thêm nhiều thuộc tính hơn.

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); 
} 
Các vấn đề liên quan