Yeah, GraphViz is a good compromise for small graphs, see http://docs.neo4j.org/chunked/snapshot/rest-api-graph-algos.html
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. On Mon, Aug 29, 2011 at 1:40 PM, Niels Hoogeveen <[email protected]>wrote: > > Peter, > I haven't put this code out yet. It has been too much in flux to share the > code yet. > I use neoclipse for visualization, which helps to check the layout of the > test graphs i am using. I would need something more programmable for the > visual output, since i use node id's of the types as property names and > relationshiptypes. This allows for renaming of types and makes it possible > to put types in namespaces and be moved from one namespace to another. Using > real names for properties and relationshiptypes is not flexible enough. As a > result the visualization in neoclipse looks pretty cryptic, having only > numbers as labels. > I will look into neo4j/neoviz to see if I can export the graph with proper > names for the relationships and properties, otherwise i can always roll my > own output program. Dot is not the most complex file format to generate. > Niels > > > Date: Mon, 29 Aug 2011 07:19:35 +0200 > > From: [email protected] > > To: [email protected] > > Subject: Re: [Neo4j] API adventures in Scalaland > > > > 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 > > _______________________________________________ > Neo4j mailing list > [email protected] > https://lists.neo4j.org/mailman/listinfo/user > _______________________________________________ Neo4j mailing list [email protected] https://lists.neo4j.org/mailman/listinfo/user

