Class: Tina4::Drivers::BoltGraphDriver
- Inherits:
-
GraphAdapter
- Object
- GraphAdapter
- Tina4::Drivers::BoltGraphDriver
- Defined in:
- lib/tina4/drivers/bolt_graph_driver.rb
Overview
The Bolt graph adapter — Neo4j + Memgraph behind the portable surface.
Instance Method Summary collapse
- #add_edge(from_id, to_id, type, properties = nil) ⇒ Object
-
#add_node(label, properties = nil) ⇒ Object
-- portable node/edge/traverse core (Cypher) -----------------------.
- #close ⇒ Object
- #delete_node(node_id) ⇒ Object
- #execute(text, params = nil) ⇒ Object
- #get_node(node_id) ⇒ Object
-
#initialize(graph_url, username: "", password: "") ⇒ BoltGraphDriver
constructor
A new instance of BoltGraphDriver.
- #neighbors(node_id, direction: "both", edge_type: nil, limit: 100) ⇒ Object
-
#query(text, params = nil) ⇒ Object
-- raw pass-through (native Cypher) --------------------------------.
- #traverse(start_id, depth: 1, direction: "both", edge_type: nil, limit: 1000) ⇒ Object
- #update_node(node_id, properties) ⇒ Object
Methods inherited from GraphAdapter
Constructor Details
#initialize(graph_url, username: "", password: "") ⇒ BoltGraphDriver
Returns a new instance of BoltGraphDriver.
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 431 def initialize(graph_url, username: "", password: "") @url = graph_url @last_error = nil timeout = Tina4.resolve_graph_connect_timeout user = graph_url.username user = username unless user && !user.empty? pwd = graph_url.password pwd = password unless pwd && !pwd.empty? user = "neo4j" if (user.nil? || user.empty?) && graph_url.engine == "bolt" && !password.to_s.empty? @conn = BoltConnection.new( host: graph_url.host, port: graph_url.port, user: user, password: pwd, connect_timeout: timeout, use_tls: graph_url.use_tls ) rescue BoltConnection::BoltConnectError => e @last_error = e. raise Tina4::GraphConnectTimeout, "Graph connect to #{graph_url.host}:#{graph_url.port} timed out or was refused " \ "(TINA4_GRAPH_CONNECT_TIMEOUT). Raise TINA4_GRAPH_CONNECT_TIMEOUT if the server is " \ "simply slow, or set it to 0 to wait indefinitely. Cause: #{e.}" end |
Instance Method Details
#add_edge(from_id, to_id, type, properties = nil) ⇒ Object
474 475 476 477 478 479 480 481 482 483 484 485 486 487 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 474 def add_edge(from_id, to_id, type, properties = nil) cypher = "MATCH (a), (b) WHERE id(a) = $from_id AND id(b) = $to_id " \ "CREATE (a)-[e:`#{type}` $props]->(b) " \ "RETURN id(e) AS id, type(e) AS type, id(a) AS f, id(b) AS t, " \ "properties(e) AS props" rows = run(cypher, { "from_id" => from_id, "to_id" => to_id, "props" => properties || {} }) return nil if rows.empty? row = rows[0] Tina4::GraphEdge.new( id: row["id"], type: row["type"], from: row["f"], to: row["t"], properties: row["props"] || {} ) end |
#add_node(label, properties = nil) ⇒ Object
-- portable node/edge/traverse core (Cypher) -----------------------
467 468 469 470 471 472 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 467 def add_node(label, properties = nil) cypher = "CREATE (n:`#{label}` $props) " \ "RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props" rows = run(cypher, { "props" => properties || {} }) node_from_row(rows[0]) end |
#close ⇒ Object
537 538 539 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 537 def close @conn&.close end |
#delete_node(node_id) ⇒ Object
503 504 505 506 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 503 def delete_node(node_id) run("MATCH (n) WHERE id(n) = $id DETACH DELETE n", { "id" => node_id }) true end |
#execute(text, params = nil) ⇒ Object
461 462 463 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 461 def execute(text, params = nil) query(text, params) end |
#get_node(node_id) ⇒ Object
489 490 491 492 493 494 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 489 def get_node(node_id) cypher = "MATCH (n) WHERE id(n) = $id " \ "RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props" rows = run(cypher, { "id" => node_id }) node_from_row(rows[0]) end |
#neighbors(node_id, direction: "both", edge_type: nil, limit: 100) ⇒ Object
508 509 510 511 512 513 514 515 516 517 518 519 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 508 def neighbors(node_id, direction: "both", edge_type: nil, limit: 100) edge = edge_type ? ":`#{edge_type}`" : "" pattern = case direction when "out" then "(n)-[#{edge}]->(m)" when "in" then "(n)<-[#{edge}]-(m)" else "(n)-[#{edge}]-(m)" end cypher = "MATCH #{pattern} WHERE id(n) = $id " \ "RETURN DISTINCT id(m) AS id, labels(m) AS labels, properties(m) AS props " \ "LIMIT #{limit.to_i}" run(cypher, { "id" => node_id }).map { |row| node_from_row(row) } end |
#query(text, params = nil) ⇒ Object
-- raw pass-through (native Cypher) --------------------------------
455 456 457 458 459 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 455 def query(text, params = nil) rows = run(text, params) columns = rows.empty? ? [] : rows[0].keys Tina4::GraphResult.new(records: rows, columns: columns) end |
#traverse(start_id, depth: 1, direction: "both", edge_type: nil, limit: 1000) ⇒ Object
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 521 def traverse(start_id, depth: 1, direction: "both", edge_type: nil, limit: 1000) # Cypher variable-length path `[*1..N]` — Neo4j AND Memgraph (the OPPOSITE # of Ultipa's GQL quantifier `{1,N}`). edge = edge_type ? ":`#{edge_type}`" : "" n = depth.to_i arrow = case direction when "out" then "-[#{edge}*1..#{n}]->" when "in" then "<-[#{edge}*1..#{n}]-" else "-[#{edge}*1..#{n}]-" end cypher = "MATCH (n)#{arrow}(m) WHERE id(n) = $start " \ "RETURN DISTINCT id(m) AS id, labels(m) AS labels, properties(m) AS props " \ "LIMIT #{limit.to_i}" run(cypher, { "start" => start_id }).map { |row| node_from_row(row) } end |
#update_node(node_id, properties) ⇒ Object
496 497 498 499 500 501 |
# File 'lib/tina4/drivers/bolt_graph_driver.rb', line 496 def update_node(node_id, properties) cypher = "MATCH (n) WHERE id(n) = $id SET n += $props " \ "RETURN id(n) AS id, labels(n) AS labels, properties(n) AS props" rows = run(cypher, { "id" => node_id, "props" => properties || {} }) node_from_row(rows[0]) end |