Class: Neo4j::Server::CypherNode
- Includes:
- Core::ActiveEntity, Core::CypherTranslator, Resource
- Defined in:
- lib/neo4j-server/cypher_node.rb
Constant Summary
Constants included from Core::CypherTranslator
Core::CypherTranslator::SANITIZE_ESCAPED_REGEXP
Constants included from PropertyValidator
PropertyValidator::VALID_PROPERTY_VALUE_CLASSES
Instance Attribute Summary
Attributes included from Resource
Instance Method Summary collapse
- #_cypher_label_list(labels) ⇒ Object
-
#_java_node ⇒ Object
TODO, needed by neo4j-cypher.
- #_map_result(r) ⇒ Object
- #add_label(*labels) ⇒ Object
-
#create_rel(type, other_node, props = nil) ⇒ Object
Creates a relationship of given type to other_node with optionally properties.
-
#del ⇒ Object
(also: #delete, #destroy)
Deletes this node from the database.
-
#exist? ⇒ Boolean
True if the node exists.
-
#get_property(key) ⇒ Object
Directly get the property on the node (low level method, may need transaction).
-
#initialize(session, value) ⇒ CypherNode
constructor
A new instance of CypherNode.
- #inspect ⇒ Object
-
#labels ⇒ Object
All the Neo4j labels for this node.
- #match(clazz, returns, match = {}) ⇒ Object
- #neo_id ⇒ Object
-
#node(match = {}) ⇒ Object
Returns the only node of a given type and direction that is attached to this node, or nil.
-
#nodes(match = {}) ⇒ Enumerable<Neo4j::Node>
abstract
Works like #rels method but instead returns the nodes.
-
#props ⇒ Hash<Symbol, Object>
All properties of the node.
-
#props=(properties) ⇒ Object
replace all properties with new properties.
- #refresh ⇒ Object
-
#rel(match = {}) ⇒ Object
Same as #node but returns the relationship.
-
#rel?(match = {}) ⇒ Boolean
Returns true or false if there is one or more relationships.
-
#rels(match = {dir: :both}) ⇒ Enumerable<Neo4j::Relationship>
Returns an enumeration of relationships.
- #remove_label(*labels) ⇒ Object
- #remove_properties(properties) ⇒ Object
-
#remove_property(key) ⇒ Object
Directly remove the property on the node (low level method, may need transaction).
- #set_label(*label_names) ⇒ Object
-
#set_property(key, value) ⇒ Object
Directly set the property on the node (low level method, may need transaction).
-
#update_props(properties) ⇒ Object
Updates the properties, keeps old properties.
Methods included from Core::ActiveEntity
Methods included from Core::CypherTranslator
#cypher_prop_list, #escape_quotes, #escape_value, #sanitize_escape_sequences, sanitized_column_names, translate_response
Methods included from Resource
#convert_from_json_value, #expect_response_code, #handle_response_error, #init_resource_data, #resource_headers, #resource_url_id, #response_exception, #wrap_resource
Methods inherited from Node
_load, #_rel, create, find_nodes, load
Methods included from PropertyContainer
Methods included from PropertyValidator
#valid_property?, #validate_property
Methods included from Node::Wrapper
Methods included from EntityEquality
Constructor Details
#initialize(session, value) ⇒ CypherNode
Returns a new instance of CypherNode.
7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/neo4j-server/cypher_node.rb', line 7 def initialize(session, value) @session = session @id = if value.is_a?(Hash) hash = value['data'] @props = Hash[hash.map{ |k, v| [k.to_sym, v] }] value['id'] # value['self'].match(/\d+$/)[0].to_i else value end end |
Instance Method Details
#_cypher_label_list(labels) ⇒ Object
113 114 115 |
# File 'lib/neo4j-server/cypher_node.rb', line 113 def _cypher_label_list(labels) ':' + labels.map{|label| "`#{label}`"}.join(':') end |
#_java_node ⇒ Object
TODO, needed by neo4j-cypher
28 29 30 |
# File 'lib/neo4j-server/cypher_node.rb', line 28 def _java_node self end |
#_map_result(r) ⇒ Object
209 210 211 |
# File 'lib/neo4j-server/cypher_node.rb', line 209 def _map_result(r) r.to_node_enumeration.map { |rel| rel.result } end |
#add_label(*labels) ⇒ Object
117 118 119 |
# File 'lib/neo4j-server/cypher_node.rb', line 117 def add_label(*labels) @session._query_or_fail("START n=node(#{neo_id}) SET n #{_cypher_label_list(labels)}") end |
#create_rel(type, other_node, props = nil) ⇒ Object
Creates a relationship of given type to other_node with optionally properties
33 34 35 36 37 38 |
# File 'lib/neo4j-server/cypher_node.rb', line 33 def create_rel(type, other_node, props = nil) q = "START a=node(#{neo_id}), b=node(#{other_node.neo_id}) CREATE (a)-[r:`#{type}` #{cypher_prop_list(props)}]->(b) RETURN ID(r)" id = @session._query_or_fail(q, true) data_hash = { 'type' => type, 'data' => props, 'start' => self.neo_id.to_s, 'end' => other_node.neo_id.to_s, 'id' => id } CypherRelationship.new(@session, data_hash) end |
#del ⇒ Object Also known as: delete, destroy
Deletes this node from the database
142 143 144 145 |
# File 'lib/neo4j-server/cypher_node.rb', line 142 def del @session._query_or_fail("START n = node(#{neo_id}) MATCH n-[r]-() DELETE r") @session._query_or_fail("START n = node(#{neo_id}) DELETE n") end |
#exist? ⇒ Boolean
Returns true if the node exists.
151 152 153 154 155 156 157 158 159 160 |
# File 'lib/neo4j-server/cypher_node.rb', line 151 def exist? response = @session._query("START n=node(#{neo_id}) RETURN ID(n)") if (!response.error?) return true elsif (response.error_status =~ /EntityNotFound/) return false else response.raise_error end end |
#get_property(key) ⇒ Object
Directly get the property on the node (low level method, may need transaction)
99 100 101 102 103 104 105 |
# File 'lib/neo4j-server/cypher_node.rb', line 99 def get_property(key) if @props @props[key.to_sym] else @session._query_or_fail("START n=node(#{neo_id}) RETURN n.`#{key}`", true) end end |
#inspect ⇒ Object
23 24 25 |
# File 'lib/neo4j-server/cypher_node.rb', line 23 def inspect "CypherNode #{neo_id} (#{object_id})" end |
#labels ⇒ Object
Returns all the Neo4j labels for this node.
108 109 110 111 |
# File 'lib/neo4j-server/cypher_node.rb', line 108 def labels r = @session._query_or_fail("START n=node(#{neo_id}) RETURN labels(n) as labels", true) r.map(&:to_sym) end |
#match(clazz, returns, match = {}) ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/neo4j-server/cypher_node.rb', line 195 def match(clazz, returns, match={}) to_dir = {outgoing: ->(rel) {"-#{rel}->"}, incoming: ->(rel) {"<-#{rel}-"}, both: ->(rel) {"-#{rel}-"} } cypher_rel = match[:type] ? "[r:`#{match[:type]}`]" : '[r]' between_id = match[:between] ? ",p=node(#{match[:between].neo_id}) " : "" dir_func = to_dir[match[:dir] || :both] cypher = "START n=node(#{neo_id}) #{between_id} MATCH (n)#{dir_func.call(cypher_rel)}(p) RETURN #{returns}" r = @session._query(cypher) r.raise_error if r.error? _map_result(r) end |
#neo_id ⇒ Object
19 20 21 |
# File 'lib/neo4j-server/cypher_node.rb', line 19 def neo_id @id end |
#node(match = {}) ⇒ Object
Returns the only node of a given type and direction that is attached to this node, or nil. This is a convenience method that is used in the commonly occuring situation where a node has exactly zero or one relationships of a given type and direction to another node. Typically this invariant is maintained by the rest of the code: if at any time more than one such relationships exist, it is a fatal error that should generate an exception.
This method reflects that semantics and returns either:
-
nil if there are zero relationships of the given type and direction,
-
the relationship if there’s exactly one, or
-
throws an exception in all other cases.
This method should be used only in situations with an invariant as described above. In those situations, a “state-checking” method (e.g. #rel?) is not required, because this method behaves correctly “out of the box.”
164 165 166 167 168 |
# File 'lib/neo4j-server/cypher_node.rb', line 164 def node(match={}) result = match(CypherNode, "p as result LIMIT 2", match) raise "Expected to only find one relationship from node #{neo_id} matching #{match.inspect} but found #{result.count}" if result.count > 1 result.first end |
#nodes(match = {}) ⇒ Enumerable<Neo4j::Node>
it’s possible that the same node is returned more than once because of several relationship reaching to the same node, see #outgoing for alternative
Works like #rels method but instead returns the nodes. It does try to load a Ruby wrapper around each node
184 185 186 |
# File 'lib/neo4j-server/cypher_node.rb', line 184 def nodes(match={}) match(CypherNode, "p as result", match) end |
#props ⇒ Hash<Symbol, Object>
Returns all properties of the node.
41 42 43 44 45 46 47 48 |
# File 'lib/neo4j-server/cypher_node.rb', line 41 def props if @props @props else hash = @session._query_entity_data("START n=node(#{neo_id}) RETURN n") @props = Hash[hash['data'].map{ |k, v| [k.to_sym, v] }] end end |
#props=(properties) ⇒ Object
replace all properties with new properties
68 69 70 71 72 |
# File 'lib/neo4j-server/cypher_node.rb', line 68 def props=(properties) refresh @session._query_or_fail("START n=node(#{neo_id}) SET n = { props }", false, {props: properties}) properties end |
#refresh ⇒ Object
50 51 52 |
# File 'lib/neo4j-server/cypher_node.rb', line 50 def refresh @props = nil end |
#rel(match = {}) ⇒ Object
Same as #node but returns the relationship. Notice it may raise an exception if there are more then one relationship matching.
171 172 173 174 175 |
# File 'lib/neo4j-server/cypher_node.rb', line 171 def rel(match={}) result = match(CypherRelationship, "r as result LIMIT 2", match) raise "Expected to only find one relationship from node #{neo_id} matching #{match.inspect} but found #{result.count}" if result.count > 1 result.first end |
#rel?(match = {}) ⇒ Boolean
Returns true or false if there is one or more relationships
178 179 180 181 |
# File 'lib/neo4j-server/cypher_node.rb', line 178 def rel?(match={}) result = match(CypherRelationship, "r as result", match) !!result.first end |
#rels(match = {dir: :both}) ⇒ Enumerable<Neo4j::Relationship>
Returns an enumeration of relationships. It always returns relationships of depth one.
190 191 192 |
# File 'lib/neo4j-server/cypher_node.rb', line 190 def rels(match = {dir: :both}) match(CypherRelationship, "r as result", match) end |
#remove_label(*labels) ⇒ Object
121 122 123 |
# File 'lib/neo4j-server/cypher_node.rb', line 121 def remove_label(*labels) @session._query_or_fail("START n=node(#{neo_id}) REMOVE n #{_cypher_label_list(labels)}") end |
#remove_properties(properties) ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/neo4j-server/cypher_node.rb', line 74 def remove_properties(properties) refresh q = "START n=node(#{neo_id}) REMOVE " + properties.map do |k| "n.`#{k}`" end.join(', ') @session._query_or_fail(q) end |
#remove_property(key) ⇒ Object
Directly remove the property on the node (low level method, may need transaction)
55 56 57 58 |
# File 'lib/neo4j-server/cypher_node.rb', line 55 def remove_property(key) refresh @session._query_or_fail("START n=node(#{neo_id}) REMOVE n.`#{key}`") end |
#set_label(*label_names) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/neo4j-server/cypher_node.rb', line 125 def set_label(*label_names) label_as_symbols = label_names.map(&:to_sym) to_keep = labels & label_as_symbols to_remove = labels - to_keep to_set = label_as_symbols - to_keep # no change ? return if to_set.empty? && to_remove.empty? q = "START n=node(#{neo_id})" q += " SET n #{_cypher_label_list(to_set)}" unless to_set.empty? q += " REMOVE n #{_cypher_label_list(to_remove)}" unless to_remove.empty? @session._query_or_fail(q) end |
#set_property(key, value) ⇒ Object
Directly set the property on the node (low level method, may need transaction)
61 62 63 64 65 |
# File 'lib/neo4j-server/cypher_node.rb', line 61 def set_property(key,value) refresh @session._query_or_fail("START n=node(#{neo_id}) SET n.`#{key}` = { value }", false, value: value) value end |
#update_props(properties) ⇒ Object
Updates the properties, keeps old properties
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/neo4j-server/cypher_node.rb', line 83 def update_props(properties) refresh return if properties.empty? removed_keys = properties.keys.select{|k| properties[k].nil?} remove_properties(removed_keys) unless removed_keys.empty? properties_to_set = properties.keys - removed_keys return if properties_to_set.empty? q = "START n=node(#{neo_id}) SET " + properties_to_set.map do |k| "n.`#{k}`= #{escape_value(properties[k])}" end.join(',') @session._query_or_fail(q) properties end |