Niels,
Is that Scala code in the graph collections? If you want, ,you could use the
neo4j/neoviz project to output .dot graphs at any point and thus visualize
what's happening in the graph to illustrate :)

/Peter

On Monday, August 29, 2011, Niels Hoogeveen <[email protected]>
wrote:
>
> In the last week I have been working on a Neo4j API in Scala, taking
navigation in the graph as primary.
>
> Just like the Enhanced API written in Java, the Scala API generalizes each
element (Node, Relationship, RelationshipType, property name and property
value) of the Neo4j database as being a Vertex.
>
> Before digging into the details of the Scala API, let's start with some
example code.
>
>    val name = Db(String("name"))
>    val friend = Db(VertexOut("FRIEND"))
>    val john = Db(NewVertex).put(name, "John")
>    val pete = Db(NewVertex).put(name, "Pete").put(friend, john)
>
> This piece of code defines the PropertyType "name" and the EdgeTypes
"FRIEND", creates two vertices for the persons "John" and "Pete", and states
that John is a friend of Pete.
>
> In standard Neo4j API this could have been written as:
>
>  Node john = db.createNode();
>  Node pete = db.createNode();
>  john.setProperty("name", "John");
>  pete.setProperty("name", "Pete");
>  pete.createRelationshipTo(john,
DynamicRelationshipType.withName("FRIEND"));
>
> Apart from an obvious style difference, there is one immediate difference
noticeable between the two API's.
>
> In the Neo4j API it is possible to write:
>
>  john.setProperty("name", "John");
>  pete.setProperty("name", 99);
>
> While the following Scala program won't typecheck:
>
>  pete.put(name, 99) //ERROR
>
> The "name" property is defined as a String and the API enforces that type.
This also applies when fetching a property value. In the Neo4j API we write:
>
>  john.getProperty("name")  // returns java.lang.Object
>
> In the Scala API we write:
>
>  john(name)   // returns java.lang.String
>
> It is also possible to ask the names of pete's friend as follows:
>
>  pete(friend andThen name)
>
> This is equal to the Neo4j call:
>
>
 (String)pete.getSingleRelationship(DynamicRelationshipType.withName("FRIEND"),
Direction.OUTGOING).endNode.getProperty("name")
>
> If pete has more than one friend, we have to define a different key to
fetch them ( the VertexOut key refers to one single relationship, either the
one to be created, or a singular exisiting relationship ):
>
>  val friends = Db(Vertices("FRIEND"))
>
> We now have a key to all "FRIEND" relationships so we can ask:
>
>  pete(friends andThen name)
>
> This returns an Iterable[String] with the names of all Pete's friends.
>
> We can even do:
>
>  pete(Rec(friends) andThen name)
>
> This returns an Iterable[String] with the names of all Pete's friends of
friends (to the n-th degree). The Rec object recursively applies "friend" to
all vertices it traverses, remembering already taken paths, traversed
Relationships or traversed Nodes (settings are optional with sensible
defaults).
>
> We can also write:
>
>  pete(Rec(friend, 2) andThen name)
>
> This returns an Iterable[String] with the names of all Pete's friends of
friends (to the 2nd degree)
>
> It is even possible to write:
>
>  pete(Rec(friend andThen friend) andThen name)
>
> This returns an Iterable[String] with the names of all Pete's friends of
friends (to the n-th degree where n is even)
>
> Instead of having get methods for properties and relationships and
traversal methods on nodes, the Scala API uses one calling pattern for all
database related objects:
>
> object(traverser)
>
> So a call like Db(String("name")) is not just a call on the database to
return a PropertyType with name "name" and datatype String, it is a
traversal from the database to that PropertyType. What is being returned
with that call is a traverser itself.
>
> Traversers can be composed with "andThen", so the output of one traverser
is used as input for the next traverser.
>
> All traversers are typed, so the "andThen" connective can only be applied
when the type of the output of the left-hand-side traverser is equal to the
type as the input of the right-hand-side traverser. This is checked at
compile time.
>
> Traversals not only work on Vertex objects and it's subtypes (Property,
PropertyType, Edge, EdgeType...), it also works on Iterable[Vertex].
>
> Instead of fetching just pete's friends, as in:
>
> pete(friends)
>
> we can also fetch the friends of pete and john:
>
> val frnds = List(pete, john)
> frnds(friends)
>
> or if we don't need the "frnds" object later on, we simply state:
>
> List(pete, john)(friends)
>
> and if we want the names of those friends:
>
> List(pete, john)(friends andThen name)
>
> it is even possible to set properties or create relationships on
Iterable[Vertex]
>
> val age = Db(Int("age"))
> val nationality = Db(String("nationality"))
> List(pete, john).put(age, 40).put(nationality, "Irish")
>
> This sets the "age" property to 40 on both "pete" and "john".
>
> It is also possible to write this as a traversal:
>
> List(pete, john)(Put(age, 40) andThen Put(nationality, "Irish"))
>
> All traversers are function objects, so they can both be called as a
function and can be treated as an object. This makes it possible to create
traverers programmatically, allowing for the storage of traversers in the
database, and many more nifty tricks.
>
> Using the Put object, we could for example create a list of such
actions/traversals and perform a validation on the list before actually
calling the put-functions.
>
> There is much more to say about the API, for example the support of n-ary
edges, but I will leave it for now. I think this approach to traversals and
the fusion of Vertex and Iterable[Vertex] is enough for now.
>
> Niels
>
>
>
>
> _______________________________________________
> Neo4j mailing list
> [email protected]
> https://lists.neo4j.org/mailman/listinfo/user
>

-- 

Cheers,

/peter neubauer

GTalk:      neubauer.peter
Skype       peter.neubauer
Phone       +46 704 106975
LinkedIn   http://www.linkedin.com/in/neubauer
Twitter      http://twitter.com/peterneubauer

http://www.neo4j.org               - Your high performance graph database.
http://startupbootcamp.org/    - Ă–resund - Innovation happens HERE.
http://www.thoughtmade.com - Scandinavia's coolest Bring-a-Thing party.
_______________________________________________
Neo4j mailing list
[email protected]
https://lists.neo4j.org/mailman/listinfo/user

Reply via email to