Skip to content

Simple Graphs

topofocus edited this page Jul 12, 2019 · 8 revisions

The basic setup: A basic-node-class and an ExtraNode class. The connection is realized through Connects-Edges.

 V.create_class :base, :node
 Node.create_class :extra_node 
 c= E.create_class :connects
 c.uniq_index

Linear Graph

Base --> Connects --> ExtraNode ---> Connects ---> ExtraNode ...

Vertex#assign creates an Edge (via argument) and connects to the spcified vertex. It returns the vertex and thus supports chaining.

def linear_elements vertex, count 
 (1..count).each{|n| vertex = vertex.assign(via: Connects, vertex: ExtraNode.create(note_count: n))}
end

# call with
 start =  Base.create some_label: 'some_value'
 linear_elements start, 200   # for 200 list-elements

Get a Vector through Vertex#traverse

Its elements (vertices) an be accessed through

vertex.traverse in_or_out, via: /pattern/, depth: some_value`, start_at: 1

> start.traverse :out, via: /con/ , depth: 100 

returns a list with 100 connected vertices. The set can be narrowed by specifying a start_vertex.

The following query is fired:

> select  from  ( traverse  outE('connects').in  from #{vertex}  while $depth <= #{depth}   ) 
>	  where $depth >= #{start_at} 

Apply a Function on the ResultSet

The database offers some functions, which can applied to the resultset. Vertex.traverse can return the query to fetch all list-elements. This is input to a OrientQuery

> the_collection = start_point.traverse :out, via: /con/, depth: 100, execute: false 
> the_query     = OrientSupport::OrientQuery.new from: the_collecion, 
	                             projection: 'median(note_count)', 
	 				  where: '$depth>=50 '
> Base.query_dataset the_query
  => [75]

Utility Method »Vector«

Anything can be tied together to a function »V.vector«. Beginning at a start-vertex, {length} nodes of the graph are traversed, the traversal stops if a condition is met {to_tg}. Any node from {start_at} to the specified or determined end is returned.

It is assumed that each vertex of the linear graph is connected to a Time Graph (via has_data-edges) and the graph-elements are tied through grid-Edges. In addition, a method datum must be present, fetching the date from the time-graph.

`# simplified and specialized form of traverse
 # 
 # start = {a vertex} on the linear graph
 #   
 # Usage: 
 #   start.vector(10) 
 #   
 #   start.vector(10, to_tg: 2.week.since(start.datum))
 #
 #   start.vector(10, function: :median){ "mean" } 
 # with 
 #  function: one of 'eval, min, max, sum abs, decimal, avg, count,mode, median, percentil, varinance, stddev'
 # and a block, specifying the  property to work with
 #
 def vector  length, where: nil, function: nil, to_tg: nil, start_at: 0
   dir =  length <0 ? :in : :out ;
   the_vector_query = traverse dir, via: /grid/, depth: length.abs, where: where, execute: false    
   the_vector_query.while "inE('ml_has_data').out != #{to_tg.rrid}  " if to_tg.present?
   t=  OrientSupport::OrientQuery.new from: the_vector_query, where: "$depth >= #{start_at}"	

   if function.present? && block_given?
	t.projection( "#{function}(#{yield})")
	query( t ){ |result| result.to_a.flatten.last}.first
   else
	query( t )	
   end
end

This utility method can be placed in the V-model-file.