Class: Neo4j::Core::Traversal::Traverser
- Inherits:
-
Object
- Object
- Neo4j::Core::Traversal::Traverser
- Includes:
- Enumerable, Neo4j::Core::ToJava
- Defined in:
- lib/neo4j-core/traversal/traverser.rb
Overview
By using this class you can both specify traversals and create new relationships. This object is return from the Neo4j::Core::Traversal methods.
Instance Method Summary collapse
-
#<<(other_node) ⇒ Neo4j::Relationship
Creates a new relationship between given node and self It can create more then one relationship.
- #[](index) ⇒ Object
- #_add_rel(dir, type) ⇒ Object
- #_new_both(other_node, type, props) ⇒ Object
- #_new_in(other_node, type, props) ⇒ Object
- #_new_out(other_node, type, props) ⇒ Object
- #both(type) ⇒ Object
-
#breadth_first(pre_or_post = :pre) ⇒ Object
Sets traversing breadth first (default).
-
#depth(d) ⇒ Object
Sets depth, if :all then it will traverse any depth.
-
#depth_first(pre_or_post = :pre) ⇒ Object
Sets traversing depth first.
-
#each ⇒ Object
Required by the Ruby Enumerable Mixin.
-
#each_raw ⇒ Object
Same as #each but does not wrap each node in a Ruby class, yields the Java Neo4j Node instance instead.
- #empty? ⇒ true, false
- #eval_paths(&eval_path_block) ⇒ Object
-
#expander(&expander) ⇒ Object
Self.
-
#filter {|path| ... } ⇒ Object
Only include nodes in the traversal in which the provided block returns true.
-
#include_start_node ⇒ Object
By default the start node is not included in the traversal Specifies that the start node should be included.
-
#incoming(type) ⇒ Object
Adds one incoming relationship type to the traversal.
-
#initialize(from, dir = :both, type = nil) ⇒ Traverser
constructor
A new instance of Traverser.
-
#iterator ⇒ Object
The java iterator.
-
#new(other_node, props = {}) ⇒ Neo4j::Relationship
Creates a new relationship between self and given node.
-
#outgoing(type) ⇒ Object
Adds one outgoing relationship type to the traversal.
-
#paths ⇒ Object
Specifies that we should return an enumerable of paths instead of nodes.
-
#prune {|path| ... } ⇒ Object
Cuts of of parts of the traversal.
- #query(query_hash = nil, &block) ⇒ Object
-
#raw ⇒ Object
If this is called then it will not wrap the nodes but instead return the raw Java Neo4j::Node objects when traversing.
-
#rels ⇒ Object
Returns an enumerable of relationships instead of nodes.
-
#to_ary ⇒ Object
Returns an real ruby array.
- #to_s ⇒ Object
-
#unique(u = :node_global) ⇒ Object
Sets the rules for how positions can be revisited during a traversal as stated in Uniqueness.
Methods included from Neo4j::Core::ToJava
dir_from_java, dir_to_java, type_to_java, types_to_java
Constructor Details
#initialize(from, dir = :both, type = nil) ⇒ Traverser
Returns a new instance of Traverser.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 62 def initialize(from, dir=:both, type=nil) @from = from @depth = 1 if type.nil? raise "Traversing all relationship in direction #{dir.inspect} not supported, only :both supported" unless dir == :both @td = Java::OrgNeo4jKernelImplTraversal::TraversalDescriptionImpl.new.breadth_first() elsif (dir == :both) both(type) elsif (dir == :incoming) incoming(type) elsif (dir == :outgoing) outgoing(type) else raise "Illegal direction #{dir.inspect}, expected :outgoing, :incoming or :both" end end |
Instance Method Details
#<<(other_node) ⇒ Neo4j::Relationship
Creates a new relationship between given node and self It can create more then one relationship
191 192 193 194 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 191 def <<(other_node) new(other_node) self end |
#[](index) ⇒ Object
332 333 334 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 332 def [](index) each_with_index { |node, i| break node if index == i } end |
#_add_rel(dir, type) ⇒ Object
279 280 281 282 283 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 279 def _add_rel(dir, type) t = type_to_java(type) d = dir_to_java(dir) @td = @td ? @td.relationships(t, d) : Java::OrgNeo4jKernelImplTraversal::TraversalDescriptionImpl.new.breadth_first().relationships(t, d) end |
#_new_both(other_node, type, props) ⇒ Object
234 235 236 237 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 234 def _new_both(other_node, type, props) _new_out(other_node, type, props) _new_in(other_node, type, props) end |
#_new_in(other_node, type, props) ⇒ Object
229 230 231 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 229 def _new_in(other_node, type, props) other_node.create_relationship_to(@from, type_to_java(type)).update(props) end |
#_new_out(other_node, type, props) ⇒ Object
224 225 226 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 224 def _new_out(other_node, type, props) @from.create_relationship_to(other_node, type_to_java(type)).update(props) end |
#both(type) ⇒ Object
241 242 243 244 245 246 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 241 def both(type) @both_rel_types ||= [] @both_rel_types << type _add_rel(:both, type) self end |
#breadth_first(pre_or_post = :pre) ⇒ Object
Sets traversing breadth first (default).
This is the default ordering if none is defined. The pre_or_post
parameter parameter can have two values: :pre
or :post
-
:pre - Traversing breadth first, visiting each node before visiting its child nodes (default)
-
:post - Traversing breadth first, visiting each node after visiting its child nodes.
Note
Please note that breadth first traversals have a higher memory overhead than depth first traversals. BranchSelectors carries state and hence needs to be uniquely instantiated for each traversal. Therefore it is supplied to the TraversalDescription through a BranchOrderingPolicy interface, which is a factory of BranchSelector instances.
124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 124 def breadth_first(pre_or_post = :pre) case pre_or_post when :pre then @td = @td.order(Java::OrgNeo4jKernel::Traversal.preorderBreadthFirst()) when :post then @td = @td.order(Java::OrgNeo4jKernel::Traversal.postorderBreadthFirst()) else raise "Unknown type #{pre_or_post}, should be :pre or :post" end self end |
#depth(d) ⇒ Object
Sets depth, if :all then it will traverse any depth
318 319 320 321 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 318 def depth(d) @depth = d self end |
#depth_first(pre_or_post = :pre) ⇒ Object
Sets traversing depth first.
The pre_or_post
parameter parameter can have two values: :pre or :post
-
:pre - Traversing depth first, visiting each node before visiting its child nodes (default)
-
:post - Traversing depth first, visiting each node after visiting its child nodes.
97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 97 def depth_first(pre_or_post = :pre) case pre_or_post when :pre then @td = @td.order(Java::OrgNeo4jKernel::Traversal.preorderDepthFirst()) when :post then @td = @td.order(Java::OrgNeo4jKernel::Traversal.postorderDepthFirst()) else raise "Unknown type #{pre_or_post}, should be :pre or :post" end self end |
#each ⇒ Object
Required by the Ruby Enumerable Mixin
342 343 344 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 342 def each @raw ? iterator.each { |i| yield i } : iterator.each { |i| yield i.wrapper } end |
#each_raw ⇒ Object
Same as #each but does not wrap each node in a Ruby class, yields the Java Neo4j Node instance instead.
347 348 349 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 347 def each_raw iterator.each { |i| yield i } end |
#empty? ⇒ true, false
337 338 339 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 337 def empty? first == nil end |
#eval_paths(&eval_path_block) ⇒ Object
137 138 139 140 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 137 def eval_paths(&eval_path_block) @td = @td.evaluator(Evaluator.new(&eval_path_block)) self end |
#expander(&expander) ⇒ Object
Returns self.
251 252 253 254 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 251 def (&) @td = @td.(RelExpander.create_pair(&)) self end |
#filter {|path| ... } ⇒ Object
Only include nodes in the traversal in which the provided block returns true.
305 306 307 308 309 310 311 312 313 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 305 def filter(&block) # we keep a reference to filter predicate since only one filter is allowed and we might want to modify it @filter_predicate ||= FilterPredicate.new @filter_predicate.add(block) @td = @td.filter(@filter_predicate) self end |
#include_start_node ⇒ Object
By default the start node is not included in the traversal Specifies that the start node should be included
326 327 328 329 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 326 def include_start_node @include_start_node = true self end |
#incoming(type) ⇒ Object
Adds one incoming relationship type to the traversal
271 272 273 274 275 276 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 271 def incoming(type) @incoming_rel_types ||= [] @incoming_rel_types << type _add_rel(:incoming, type) self end |
#iterator ⇒ Object
Returns the java iterator.
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 374 def iterator unless @include_start_node if @filter_predicate @filter_predicate.include_start_node else @td = @td.filter(Java::OrgNeo4jKernel::Traversal.return_all_but_start_node) end end @td = @td.prune(Java::OrgNeo4jKernel::Traversal.pruneAfterDepth(@depth)) unless @depth == :all if @traversal_result == :rels @td.traverse(@from._java_node).relationships elsif @traversal_result == :paths @td.traverse(@from._java_node).iterator else @td.traverse(@from._java_node).nodes end end |
#new(other_node, props = {}) ⇒ Neo4j::Relationship
Creates a new relationship between self and given node. It can create more then one relationship This method is used by the <<
operator.
217 218 219 220 221 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 217 def new(other_node, props = {}) @outgoing_rel_types && @outgoing_rel_types.each { |type| _new_out(other_node, type, props) } @incoming_rel_types && @incoming_rel_types.each { |type| _new_in(other_node, type, props) } @both_rel_types && @both_rel_types.each { |type| _new_both(other_node, type, props) } end |
#outgoing(type) ⇒ Object
Adds one outgoing relationship type to the traversal
260 261 262 263 264 265 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 260 def outgoing(type) @outgoing_rel_types ||= [] @outgoing_rel_types << type _add_rel(:outgoing, type) self end |
#paths ⇒ Object
Specifies that we should return an enumerable of paths instead of nodes.
367 368 369 370 371 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 367 def paths @traversal_result = :paths @raw = true self end |
#prune {|path| ... } ⇒ Object
Cuts of of parts of the traversal.
292 293 294 295 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 292 def prune(&block) @td = @td.prune(PruneEvaluator.new(block)) self end |
#query(query_hash = nil, &block) ⇒ Object
80 81 82 83 84 85 86 87 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 80 def query(query_hash = nil, &block) # only one direction is supported rel_types = [@outgoing_rel_types, @incoming_rel_types, @both_rel_types].find_all { |x| !x.nil? } raise "Only one direction is allowed, outgoing:#{@outgoing_rel_types}, incoming:#{@incoming_rel_types}, @both:#{@both_rel_types}" if rel_types.count != 1 start_id = @from.neo_id dir = (@outgoing_rel_types && :outgoing) || (@incoming_rel_types && :incoming) || (@both_rel_types && :both) CypherQuery.new(start_id, dir, rel_types.first, query_hash, &block) end |
#raw ⇒ Object
If this is called then it will not wrap the nodes but instead return the raw Java Neo4j::Node objects when traversing
360 361 362 363 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 360 def raw @raw = true self end |
#rels ⇒ Object
Returns an enumerable of relationships instead of nodes
353 354 355 356 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 353 def rels @traversal_result = :rels self end |
#to_ary ⇒ Object
Returns an real ruby array.
197 198 199 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 197 def to_ary self.to_a end |
#to_s ⇒ Object
175 176 177 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 175 def to_s "NodeTraverser [from: #{@from.neo_id} depth: #{@depth}" end |
#unique(u = :node_global) ⇒ Object
Sets the rules for how positions can be revisited during a traversal as stated in Uniqueness.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 146 def unique(u = :node_global) case u when :node_global then # A node cannot be traversed more than once. @td = @td.uniqueness(Java::OrgNeo4jKernel::Uniqueness::NODE_GLOBAL) when :node_path then # For each returned node there 's a unique path from the start node to it. @td = @td.uniqueness(Java::OrgNeo4jKernel::Uniqueness::NODE_PATH) when :node_recent then # This is like NODE_GLOBAL, but only guarantees uniqueness among the most recent visited nodes, with a configurable count. @td = @td.uniqueness(Java::OrgNeo4jKernel::Uniqueness::NODE_RECENT) when :none then # No restriction (the user will have to manage it). @td = @td.uniqueness(Java::OrgNeo4jKernel::Uniqueness::NONE) when :rel_global then # A relationship cannot be traversed more than once, whereas nodes can. @td = @td.uniqueness(Java::OrgNeo4jKernel::Uniqueness::RELATIONSHIP_GLOBAL) when :rel_path then # No restriction (the user will have to manage it). @td = @td.uniqueness(Java::OrgNeo4jKernel::Uniqueness::RELATIONSHIP_PATH) when :rel_recent then # Same as for NODE_RECENT, but for relationships. @td = @td.uniqueness(Java::OrgNeo4jKernel::Uniqueness::RELATIONSHIP_RECENT) else raise "Got option for unique '#{u}' allowed: :node_global, :node_path, :node_recent, :none, :rel_global, :rel_path, :rel_recent" end self end |