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.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 52 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
181 182 183 184 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 181 def <<(other_node) new(other_node) self end |
#[](index) ⇒ Object
322 323 324 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 322 def [](index) each_with_index { |node, i| break node if index == i } end |
#_add_rel(dir, type) ⇒ Object
269 270 271 272 273 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 269 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
224 225 226 227 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 224 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
219 220 221 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 219 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
214 215 216 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 214 def _new_out(other_node, type, props) @from.create_relationship_to(other_node, type_to_java(type)).update(props) end |
#both(type) ⇒ Object
231 232 233 234 235 236 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 231 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.
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 114 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
308 309 310 311 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 308 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.
87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 87 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
332 333 334 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 332 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.
337 338 339 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 337 def each_raw iterator.each { |i| yield i } end |
#empty? ⇒ true, false
327 328 329 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 327 def empty? first == nil end |
#eval_paths(&eval_path_block) ⇒ Object
127 128 129 130 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 127 def eval_paths(&eval_path_block) @td = @td.evaluator(Evaluator.new(&eval_path_block)) self end |
#expander(&expander) ⇒ Object
Returns self.
241 242 243 244 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 241 def (&) @td = @td.(RelExpander.create_pair(&)) self end |
#filter {|path| ... } ⇒ Object
Only include nodes in the traversal in which the provided block returns true.
295 296 297 298 299 300 301 302 303 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 295 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.evaluator(@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
316 317 318 319 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 316 def include_start_node @include_start_node = true self end |
#incoming(type) ⇒ Object
Adds one incoming relationship type to the traversal
261 262 263 264 265 266 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 261 def incoming(type) @incoming_rel_types ||= [] @incoming_rel_types << type _add_rel(:incoming, type) self end |
#iterator ⇒ Object
Returns the java iterator.
364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 364 def iterator unless @include_start_node @td = @td.evaluator(Java::OrgNeo4jGraphdbTraversal::Evaluators.exclude_start_position) end @td = @td.evaluator(Java::OrgNeo4jGraphdbTraversal::Evaluators.toDepth(@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.
207 208 209 210 211 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 207 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
250 251 252 253 254 255 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 250 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.
357 358 359 360 361 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 357 def paths @traversal_result = :paths @raw = true self end |
#prune {|path| ... } ⇒ Object
Cuts of of parts of the traversal.
282 283 284 285 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 282 def prune(&block) @td = @td.evaluator(PruneEvaluator.new(block)) self end |
#query(query_hash = nil, &block) ⇒ Object
70 71 72 73 74 75 76 77 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 70 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
350 351 352 353 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 350 def raw @raw = true self end |
#rels ⇒ Object
Returns an enumerable of relationships instead of nodes
343 344 345 346 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 343 def rels @traversal_result = :rels self end |
#to_ary ⇒ Object
Returns an real ruby array.
187 188 189 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 187 def to_ary self.to_a end |
#to_s ⇒ Object
165 166 167 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 165 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.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/neo4j-core/traversal/traverser.rb', line 136 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 |