DEV Community

loading...

ActiveOrient: Inheritance, Edges and Nodes

topofocus profile image Hartmut B. Updated on ・3 min read

This is Part 3 of the ActiveOrient Series.

In Part 2 we investigated similarities between RDMS(ActiveRecord)-Joins and unidirectional links and joins in ActiveOrient.

Our example Database consisting of Persons, wo are either father, child or (implicitly) parent enabled queries like

  • Which are the grandchilds of a father (Person.grandchilds( of: 'Reimund' ) remember?
  • Who is a father?
  • Who does not have children.

For now, we stick by our Person class, but organize the data with directional links and introduce inheritance.

Inheritance

In the self-referential approach, a child is a child, because there is a link in the children-property of Person. If we have to decide, if some action is allowed for the Person, we have to query the database and look for those entries. Thats inefficient.

 > Person.create_class :child, :father
  # INFO->CREATE CLASS child EXTENDS person
  # INFO->CREATE CLASS father EXTENDS person
 => [Child, Father]
Enter fullscreen mode Exit fullscreen mode

creates inherit classes. A Child, its a specialized Person. In the model-file (/model/child.rb) we can express this be defining customized methods. As expected, children and fathers are persons:

 > ['Andrea','Susi','Seema'].map  {|c| Child.create name: c}
 > ["Otto","Joseph"].map  { |c| Father.create name: c}
 > Person.count     => 5
 > Father.count     => 2
Enter fullscreen mode Exit fullscreen mode

Instead of querying the database for occurrences of a reference to a person record in Person.children, we just ask for the Class and know, this is a child. To list all children, we don't have to query all persons, we just express Child.query.order(name: :asc).execute. Much better.

The implementation does not require changes to our database-schema. Anything works with self-referential links, as before. And it is still static. So let change this.

Edges and Nodes

The most common feature of a Graph-Database is the presence of Vertices and Edges. Our present approach uses only Vertices.

  • Edges connect Vertices bidirectional.
  • Any Vertex has special properties: in and out which are arrays of links to Edges.
  • ActiveOrient provides a method nodes. It follows the attached edge and lists any Vertex present »on the other side of the Edge«.
  • Vertices are connected through the method :assign.

Assuming, we want to represent the relationships of persons, created above,

 > E.create_class :is_family
 > IS_FAMILY.create_class :is_child, :is_father
 > hugo =  Person.create( name: 'Hugo')
 > hugo.assign( via: IS_CHILD, vertex: Child.like( 'name = S*'))
 # INFO->select from child where name.left(1) = 'S' order by name asc
 # INFO->CREATE EDGE is_child from #29:6 to [#54:0, #53:0] 
 > hugo.assign( via: IS_FATHER, vertex: Father.where( name: 'Otto'))
 # INFO->CREATE EDGE is_father from #29:6 to [#59:0]
 # then
 > hugo.reload!
 > hugo.nodes( :out, via: /is/).count  => 3
 > hugo.nodes( :out, via: IS_FATHER ).first.name => 'otto'
 > Child.where( name: 'Seema').first.nodes( :in).to_human 
 => ["<Person[29:6]: out: {IS_FATHER=>1, IS_CHILD=>2}, name : Hugo>"] 

Enter fullscreen mode Exit fullscreen mode

First, we create inherent Edges: IS_Family, IS_CHILD and IS_FATHER.

Note: In ActiveOrient Edge-Classes are UPERCASE. The database-classes are still lowercase.

»hugo«, a person, is created. The new record is then assigned through IS_CHILD-Edges to any child-record meeting the search criteria. We managed to connect Susi and Seema. This is followed by an assignment of Otto via IS_FATHER.

At last, we queried the relationships. The method :nodes distinguishes between :in-going and :out-going edges. The assignment occurs on the :out side of »hugo«. The :via-parameter filters the edges, either by providing the EDGE_CLASS or an regular expression, which fits the lowercase database class names.
Nodes work in both directions. That's demonstrated in the last query. We start with a Child and ask any relationship. There is only one, to the father-vertex.

Perhaps you get the idea: This is not the end. Its very simple, to investigate the relationships of the father, for instance, to display the grandparents, their children and so on.

Conclusion

Inheritance and the flexibility of the graphical vertex & edge approach open sudden opportunities. ActiveOrient provides some methods to ease the transformation for people (like the author) who thought »relational« their hole life.

This opens many opportunities. As in real life: Its often more comfortable, to live in a well grounded environment with simple rules then to be responsible for a decent path. With ActiveOrient (and OrientDB) the developer can choose, to work with relations or graphs and s/he can benefit from proven layouts from both worlds.

In the next part, we will develop a time-graph, able to efficiently organize any time-based data, events, time-series and more.

Discussion (0)

pic
Editor guide