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

