Hi Jim,
For some reason I don't see my original comment anymore, but I'd love
to talk a bit more about my experiences.
Let's first start with the basics. Neo4j is a schemaless database,
something I greatly appreciate since it allowed me to create my own
schema on top of the graph store. In order to do that, I started by
wrapping the entire Neo4j API in Scala.
Having classes such as PropertyType and RelationhipType, made it
possible to move all graph traversal and manipulation towards those
types.
Where the Neo4j API has all graph manipulation methods on the Node, in
multispective.com all those methods have been moved towards
PropertyType and RelationshipType, making it possible to plug in
different implementations where needed. E.g. there is a
RelationshipListType, which places all relationships in an ordered
list (in-graph), but can be treated like an ordinary RelationshipType
in the API.
Another aspect of the schema is that every database element derives
from the same base class (Vertex). As a result, properties and
relationships can be treated as if they were Nodes, and both can have
properties and relationships themselves. This is achieved through the
use of shadow-nodes, where each property or relationship can have an
associated node, on which properties and relationships are stored.
This is done on a per-need basis, so only those properties that
require properties and/or relationships and relationships that require
relationships, have such a shadow node (a much nicer solution than
having to use a bipartite layout throughout the graph).
By giving every database element the same base class, access-control
becomes rather easy, since it can be handled in the base class.
Multitenency is achieved by modeling each user or user-group as a
separate domain. Each domain has its own associated namespace where
domain owners can define their own ContentTypes, PropertyTypes and
RelationshipTypes, while each domain can also import schema
definitions from other domains (if allowed by the owners of those
domains).
Within the various types, domain owners can model URL-paths, so each
domain can have it's own URL-structure if such is needed. Each URL-
path can have associated HTML templates, CSS code and Javascript code
that will be used to produce the required HTML output.
Example:
Suppose we have a blog entry stored at
mydomain.com/blog/niels/
my_first_blog_entry.
Template resolution starts looking for templates/css/javascript
associated with that particular URL (which is represented in the
database as a Node). If no templates (also stored in the database as a
Node) are found at that level, the search will continue for the path:
mydomain.com/blog/niels/. Again if nothing is found, search with
continue for the path
mydomain.com/blog/. Finally if nothing is found
up to the path
mydomain.com, default template/css/javascript is used
----
Domain owners can add their own templates/css/javascript (at least the
ones that pay for their subscription, free-user accounts don't have
this option) and with that have complete control over the rendered
output.
Altogether the experience of building this on top of Neo4j has been a
positive experience. The choice for Scala as a programming language
too has helped a lot creating this beast, especially due to the superb
collection libraries and the use of higher-order functions.
At times, I have missed the option to have a proper key-value store,
although Lucene can be used for that purpose, but isn't as fast as a
dedicated key-value store.
Another observation is that thinking in traversals over a graph makes
a lot of sense for a Content Management System. After all, most of the
database retrievals are local to a given entity.
One drawback I have noticed so far, relative to an RDBMS, is that sort
order requires more advanced planning and isn't straigtforwardly
supported at the database level. Hopefully in some future release
(neo4j 2.0) the relationship store can be completely redesigned in
order to allow for fast access to specific relationships with a given
sort-order.
Niels