Skip to content

Latest commit

 

History

History
147 lines (113 loc) · 2.86 KB

DATAMODELING.md

File metadata and controls

147 lines (113 loc) · 2.86 KB

Here you see the syntax of the declaration of Saul graph. Most of these features are unit tested in GraphQueriesTest.

Node collections

Definition:

val n = node[A]

Get all the instances of a node:

n()

To start querying using a custom collection:

val coll: Iterable[A] = ...
n(coll)

Edge Queries

Definition:

val n2 = node[B]
val e = edge(n,n2)

Get all neighbors of all instances of n:

n() ~> e

Get all neighbors of some of the instances of n:

n(coll) ~> e

Reverse Query, get all neighbors of all instances of n2:

n2() ~> -e

Property Queries

Definition:

val p=property[A]{
   x : A => property_sensor(x)
   }

Get the property of a specific instance x:

p(x)

It would be nicer if we can have: x.p

and

n(x) ~> edge1 ~>edge2 p

which provides a collection of all p property values of all nodes that we get after edge2. Properties have a core which is a basic data type b, such as String, Int, etc or an Iterable[b]. So property functions should be able to be applied on single instances or a set of instances.

Filtering Queries

Filter the instances of a node:

def f: A => Boolean = ...
n() filter f

Filter a collection of instances:

n(coll) filter f

Note that this is different from n.filter(f) or coll.filter(f) since you can continue the graph query:

n(coll) filter f ~> e

Aggregation

  • Applying a property p on a set of instances X:
node(X).p.aggregation1
  • Aggregation functions:

-- Features with nominal values

String aggregations, mainly concatenation

-- Integer and Real Features

Numerical aggregations such as sum, multiplication, max, min, ...

Filtering based on properties

node(n) filter (a logical expression over p)

This implies we need to implement the following functions for properties: equality of one property with a value, equality of two properties, p.contains(x), etc. This seems to be trivial to do or even simply granted by Scala for the most cases because the properties return basic types or collections of them.

Example Combinations

val n1 = node[A]
val n2 = node[B]
val n3 = node[C]

val e1 = edge(n1, n2)
val e2 = edge(n2, n3)


n1()
n1() ~> e1 // = n2
n1() ~> e1 ~> e2 // = n3

n3() ~> -e2 // = n2
n3() ~> -e2 ~> -e1 // = n1

##More contextual queries

getting neighbors of a node

  n1(a)~>*

getting neighbors of a node within a specific distance:

   n1(a)~>e(2)
   n1(a)~>e(-2,2)

getting the properties of the neighbors:

n(a)~>e(2).p
n(a)~>e(-2,2).p.aggregate

finding path between two nodes

n1(a).path(n2(b))