The example of the tag library and countries/sub-divisions are not necessarily 
similar. The first shows the need to model the properties of a class.

The second example shows the need to have singleton classes, which is a 
different concept, and something that cannot be done out of the box, but I will 
show a solution that requires minimal modifications to the current software.

Suppose we want to model "countries" and their "sub-divisions".

We do the following:

create class "country"
create class "sub-division"
create property "has-sub-division"
make "has-subdivision" a property of "country"

Now we like to populate the database, since all countries have different types 
of sub-divisions we need to create those:

create class "french_region"
create class "canadian_province"
create class "canadian_territory"
create class "US_state"
etc.

Populate the various classes with instances:

create node for "Alsace" and make it an instance of "french_region"
create node for "Aquitaine" and make it an instance of 
"french_region"
create node for "Alberta" and make it an instance of 
"Canadian_province"
create node for "Nanavut" and make it an instance of 
"Canadian_territory"
create node for "British Columbia" and make it an instance of 
"Canadian_province"
create node for "Alabama" and make it an instance of 
"US_State"
create node for "Alaska" and make it an instance of 
"US_State"
etc.

We'd like to state that each country has its own restriction on the type of 
subdivision. To do that we need to create classes for each country.

create class "France" 
create class "Canada"
create class "United_States_of_America"
etc.

make class "France" a subclass of "Country"
make class "Canada" a subclass of "Country"
make class "United_States_of_America" a subclass of "Country"
etc.

create restriction for "France" on "has-sub-division" with range 
"french_province" and cardinality = 26
create restriction for "Canada" on "has-sub-division" with range 
"canadian_province" and cardinality = 10
create restriction for "Canada" on "has-sub-division" with range 
"canadian_territory" and cardinality = 3
create restriction for "United_States_of_America" on "has-sub-division" with 
range "US_State" and cardinality = 50
etc.

Now we have classes for each country, but no instances. Unfortunately we cannot 
say that a class is an instance of itself, that would require a relationsship 
where the endnode equals the startnode, which Neo4J doesn't allow. So we have 
to create separate instances for each country.

create node for "France"
create node for "Canada"
create node for "United_States_Of_America"
etc.

make node "France" an instance of class "France"
make node "Canada" an instance of class "Canada"
make node "United_States_of_America" an instance of class 
"United_States_of_America"

And finally link the subdivisions to their countries:

 "France" "has-sub-division" "Alsace" 
"France" "has-sub-division" "Aquitaine" 
"Canada" "has-sub-division-of" "Alberta" 
"Canada" "has-subdivision" "British Columbia" 
"Canada" "has-subdivision" "Nanavut" 
"United_States_of_America" "has-sub-division" "Alabama" 
"United_States_of_America" "has-sub-division" "Alaska"

So we end up having a class for each country and an instance for each country.

Writing this down, I realize the patch I sent you a few days ago, contains a 
minor flaw, that needs to be fixed. In that patch I added an indexed property 
"uri" to the meta model, to bring it in line with what is being done in the RDF 
module, and to make certain that the same URI is not used for two different 
properties. Without unicity a class can have several different ProperyTypes 
with the same name. In that situation the lookup of the PropertyType of a 
property or relationship becomes impossible.

The flaw in my patch is the name of the "uri" property, which should be 
something like "class_uri". That way the class of each country can be given the 
same URI as the instance of each country, because they live in different name 
spaces. 

This same technique is used in OWL to provide "punning". An instance and a 
class can have the same URI, because instances in OWL live in a different 
namespaces from classes. 

Through the use of the "uri" property and the "class_uri" property we can also 
distill that each country class is a singleton class, because there exists an 
instance with the same URI. That way we can work around the limitation that 
relationships cannot have the same start and end node. 

Furthermore, it allows for some extra restrictions to MetaModelClass with the 
following logic: If a class has exactly one instance where the "uri" of that 
instance equals the "class_uri" of the class, no more instances can be added 
And if there is an instance of a class without a "uri" that equals the 
"class_uri", no instances can be added where the "uri" of the instance equals 
the "class_uri" of the class. With that logic, we have proper singleton classes 
in the meta model of Neo4J.

Kind regards,
Niels Hoogeveen

> Date: Thu, 8 Apr 2010 11:37:37 +0200
> From: matt...@neotechnology.com
> To: user@lists.neo4j.org
> Subject: Re: [Neo] meta meta classes
> 
> 2010/3/30 Niels Hoogeveen <pd_aficion...@hotmail.com>
> 
> >
> > MetaModelObject already has a getter (without using the word "get") to
> > access the node.
> >
> > Wrapping MetaModelObject to give it a Node-interface makes it possible to
> > directly write:
> >
> > metalObject.setProperty("a", b)
> >
> > instead of
> >
> > metaobject.node.setPropert("a", b)
> >
> > If that were all, I wouldn't make a post about it. The more interesting
> > part is the meta modeling of the node gotten from a MetaModelObject. This
> > node represents the class, but it is not an instance of any class itself.
> > That's where the reify method comes into play, which takes the node from a
> > MetaModelObject and creates a class with the same name, but in a different
> > namespace, and makes the node an instance of this new class.
> >
> > With that construction it becomes possible to model the
> > relationships/properties of a class.
> >
> > There are many examples where this can be handy.
> >
> > I already gave the example of HTML tags, where the attributes can be
> > modeled as properties and the tagname as a property of the meta class.
> >
> > Another example is:
> >
> > All countries have subdivision. Countries and their subdivisions all are
> > instances of a certain class. There is one class for country, but there is a
> > set of classes for subdivisions. In some countries, a subdivision is called
> > "province", in others it's a "state" or a "district". Subdivision of various
> > countries can have different sets of properties and relations.
> >
> > How to model the fact that the instance "United States of America" has
> > subdivisions of the class "State_(US)"? Using the reify method we can make a
> > class "United States of America", where we can model that the ClassRange of
> > "State_(US)" is "United States of America". Or if we want the relationship
> > to point the other way, that the "United States of America" has 50 (use of
> > cardinality) subdivisions of the class "State_(US)".
> >
> Here you take a step into modeling the actual data into the meta model which
> describes the data. Is it desirable to first model exactly how the data will
> look, and then add data so that it looks like that? I get a feeling that the
> data is described twice here...
> 
> >
> > Of course all this can directly be expressed with nodes and relationships,
> > but that's what the meta model does anyway.
> >
> > I do have one peeve with the meta model API. The class DataRange has a
> > constructor:
> >
> > DataRange(String datatype, Object... values)
> >
> > I'd much rather see a new Restrictable class Datavalue, and see a
> > constructor:
> >
> > DataRange(String datatype, Datavalue... values)
> >
> > That way the possible values a property can have additional properties and
> > relationships (eg. link to Wordnet definition or Wikipedia entry).
> >
> > Kind regards,
> > Niels Hoogeveen
> >
> >
> >
> >
> >
> >
> > > Date: Tue, 30 Mar 2010 09:30:10 +0200
> > > From: matt...@neotechnology.com
> > > To: user@lists.neo4j.org
> > > Subject: Re: [Neo] meta meta classes
> > >
> > > Would making the underlying Node publically available (via a getter) be
> > > virtually the same thing? In that case the meta model classes could have
> > > such a getter.
> > >
> > > 2010/3/26 Niels Hoogeveen <pd_aficion...@hotmail.com>
> > >
> > > >
> > > > Hi Peter,
> > > >
> > > > I added a Wiki entry in my github repo called "Reification of meta
> > classes
> > > > and meta properties":
> > > >
> > > >
> > > >
> > http://wiki.github.com/NielsHoogeveen/Scala-Neo4j-utils/reification-of-meta-classes-and-meta-properties
> > > >
> > > > The source code for the Scala wrappers can be found found in my repo:
> > > >
> > > > http://github.com/NielsHoogeveen/Scala-Neo4j-utils
> > > >
> > > > Kind regards,
> > > > Niels Hoogeveen
> > > >
> > > > > From: neubauer.pe...@gmail.com
> > > > > Date: Fri, 26 Mar 2010 17:25:01 +0100
> > > > > To: user@lists.neo4j.org
> > > > > Subject: Re: [Neo] meta meta classes
> > > > >
> > > > > Awesome Niels!
> > > > >
> > > > > maybe you could blog or document some cool example on this?
> > > > >
> > > > > Cheers,
> > > > >
> > > > > /peter neubauer
> > > > >
> > > > > COO and Sales, Neo Technology
> > > > >
> > > > > 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://www.tinkerpop.com      - Processing for Internet-scale
> > graphs.
> > > > > http://www.thoughtmade.com - Scandinavias coolest Bring-a-Thing
> > party.
> > > > >
> > > > >
> > > > >
> > > > > On Fri, Mar 26, 2010 at 5:22 PM, Niels Hoogeveen
> > > > > <pd_aficion...@hotmail.com> wrote:
> > > > > >
> > > > > > Using Scala, I was actually able to extend MetaModelThing to act as
> > a
> > > > Node and MetaModelClass to have shadowing functionality for both
> > > > MetaModelClasses and for MetaModelProperties, without touching the
> > original
> > > > source code.
> > > > > >
> > > > > >> To: user@lists.neo4j.org
> > > > > >> From: rick.bullo...@burningskysoftware.com
> > > > > >> Date: Fri, 26 Mar 2010 14:29:03 +0000
> > > > > >> Subject: Re: [Neo] meta meta classes
> > > > > >>
> > > > > >> Such are the joys and challenges of frameworks and abstractions.
> > > >  Sometimes you do need to get "close to the metal" though, to achieve
> > > > specific functional and performance requirements.  Thus the reason open
> > > > source frameworks are awesome.  At least we can change and extend them
> > more
> > > > easily!
> > > > > >>
> > > > > >>
> > > > > >>
> > > > > >> -----Original Message-----
> > > > > >> From: Niels Hoogeveen <pd_aficion...@hotmail.com>
> > > > > >> Date: Fri, 26 Mar 2010 15:20:15
> > > > > >> To: <user@lists.neo4j.org>
> > > > > >> Subject: Re: [Neo] meta meta classes
> > > > > >>
> > > > > >>
> > > > > >> Making MetaModelThing implement the Node interface is actually
> > > > orthogonal to the creation of Shadow objects. Though it does make code
> > using
> > > > classes as objects cleaner, and allows the node property of
> > MetaModelThing
> > > > to become private.
> > > > > >>
> > > > > >> > From: pd_aficion...@hotmail.com
> > > > > >> > To: user@lists.neo4j.org
> > > > > >> > Date: Fri, 26 Mar 2010 14:38:08 +0100
> > > > > >> > Subject: Re: [Neo] meta meta classes
> > > > > >> >
> > > > > >> >
> > > > > >> > Or, and this probably the simplest solution. Let a
> > MetaModelThing
> > > > implement the Node interface. This allows a class to be an instance of
> > > > another class and/or a SubType of another class.
> > > > > >> >
> > > > > >> >
> > > > > >> > > From: pd_aficion...@hotmail.com
> > > > > >> > > To: user@lists.neo4j.org
> > > > > >> > > Date: Fri, 26 Mar 2010 14:20:07 +0100
> > > > > >> > > Subject: Re: [Neo] meta meta classes
> > > > > >> > >
> > > > > >> > >
> > > > > >> > > The class as object phenomenon is actually quite pervasive,
> > and I
> > > > think it is possible to have a generalized solution for it.
> > > > > >> > >
> > > > > >> > > After sending this email yesterday, I came up with a slightly
> > > > different solution.
> > > > > >> > >
> > > > > >> > > val taggable = namespace.getMetaClass("taggable", true)
> > > > > >> > >
> > > > > >> > > val tagName = metaModelNamespace.getMetaProperty("tagname",
> > true)
> > > > > >> > > tagName.setCardinality(1)
> > > > > >> > >
> > > > > >> > > val metaTaggable = metaModelNamespace.getMetaClass("taggable",
> > > > true)
> > > > > >> > > metaTaggable.getDirectProperties.add(tagName)
> > > > > >> > > metaTaggable.getDirectInstances.add(taggable.node)
> > > > > >> > >
> > > > > >> > > val body = namespace.getMetaClass("body", true)
> > > > > >> > > taggable.getDirectSubs.add(body)
> > > > > >> > >
> > > > > >> > > Instead of directly relating the class "body" to the meta
> > class
> > > > "taggable", I create a shadow of the meta class "taggable" with the
> > same
> > > > name in the namespace of the class "body", and make "body" a subclass
> > of
> > > > this shadow. That way the sub classing relationship remains nicely in
> > one
> > > > name space, while the instance relationship transcends name spaces, as
> > it
> > > > should.
> > > > > >> > >
> > > > > >> > > This could in principle be generalized by adding a methods to
> > > > MetaModelClass:
> > > > > >> > >
> > > > > >> > > public MetaModelClass createShadowClass(NameSpace ns){
> > > > > >> > >
> > > > > >> > >     MetaModelClass mc = ns.getMetaClass(this.getName(), true);
> > > > > >> > >     this.getDirectInstances.add(mc.node);
> > > > > >> > >     return mc;
> > > > > >> > > }
> > > > > >> > >
> > > > > >> > > This returns a shadow of a given MetaModelClass in a given
> > > > namespace and adds it as a an instance of this.
> > > > > >> > >
> > > > > >> > > It would of course be nicer to have a method with the
> > signature:
> > > > > >> > >
> > > > > >> > > public MetaModelClass getShadow(NameSpace ns, Boolean create)
> > > > > >> > >
> > > > > >> > > This is much more in line with the rest of the API, but
> > requires a
> > > > way to find out the namespace a given MetaModelClass is defined in. I
> > didn't
> > > > see a method getNamespace() for a given class, and didn't delve deeply
> > > > enough in the source code to figure out how to do that.
> > > > > >> > >
> > > > > >> > > A similar approach can of course also be applied to
> > > > MetaModelProperties, by adding the following method to MetaModelClass:
> > > > > >> > >
> > > > > >> > > public MetaModelProperty
> > > > > >> > > createShadowProperty(NameSpace ns){
> > > > > >> > >
> > > > > >> > >
> > > > > >> > >
> > > > > >> > >     MetaModelProperty mp =
> > > > > >> > > ns.getMetaProperty(this.getName(), true);
> > > > > >> > >
> > > > > >> > >
> > > > > >> > > this.getDirectInstances.add(mp.node);
> > > > > >> > >
> > > > > >> > >     return mp;
> > > > > >> > >
> > > > > >> > > }
> > > > > >> > >
> > > > > >> > >
> > > > > >> > > This way the underlying node of a MetaModelProperty can
> > properly
> > > > be used as a class of its own and have properties, relationships, that
> > can
> > > > be further modeled in the meta layer. This e.q. allows to set a default
> > > > rendering format for a given property class.
> > > > > >> > >
> > > > > >> > > I don't see a MetaModelRelationships, which is unfortunate,
> > since
> > > > that would allow the modeling of the properties of a Relationship.
> > > > > >> > >
> > > > > >> > >
> > > > > >> > > Kind regards,
> > > > > >> > > Niels Hoogeveen
> > > > > >> > >
> > > > > >> > >
> > > > > >> > > > Date: Fri, 26 Mar 2010 11:26:29 +0100
> > > > > >> > > > From: matt...@neotechnology.com
> > > > > >> > > > To: user@lists.neo4j.org
> > > > > >> > > > Subject: Re: [Neo] meta meta classes
> > > > > >> > > >
> > > > > >> > > > That's an interresting case you've got here and it looks to
> > me
> > > > like it's
> > > > > >> > > > probably the best way to model it in the meta model.
> > > > > >> > > >
> > > > > >> > > > 2010/3/25 Niels Hoogeveen <pd_aficion...@hotmail.com>
> > > > > >> > > >
> > > > > >> > > > >
> > > > > >> > > > > For my application, I want to model an HTML template in
> > Neo4J,
> > > > using the
> > > > > >> > > > > MetaModel api.
> > > > > >> > > > >
> > > > > >> > > > > So I started setting up MetaModelClasses for the various
> > HTML
> > > > entities.
> > > > > >> > > > >
> > > > > >> > > > > e.g. (code in Scala)
> > > > > >> > > > >
> > > > > >> > > > > val classProp = namespace.getMetaProperty("class", true)
> > > > > >> > > > > val idProp =
> > > > > >> > > > > namespace.getMetaProperty("id", true)
> > > > > >> > > > > idProp.setCardinality(1)
> > > > > >> > > > >
> > > > > >> > > > >
> > > > > >> > > > > val body = namespace.getMetaClass("body", true)
> > > > > >> > > > > body.getDirectProperties(classProp)
> > > > > >> > > > > body.getDirectProperties(idProp)
> > > > > >> > > > >
> > > > > >> > > > >
> > > > > >> > > > > Which creates a class named "body" which has a property
> > named
> > > > "class"
> > > > > >> > > > > without a cardinality restriction and a property named
> > "id"
> > > > with a
> > > > > >> > > > > cardinality restriction of 1.
> > > > > >> > > > >
> > > > > >> > > > > Now I can create nodes of class "body" with various values
> > for
> > > > "class" and
> > > > > >> > > > > for "id".
> > > > > >> > > > >
> > > > > >> > > > > So far so good, but now I want to say that the class body
> > has
> > > > a property
> > > > > >> > > > > "tagname" which should get the value "body".
> > > > > >> > > > >
> > > > > >> > > > > The meta model itself doesn't allow classes to have
> > > > properties, but it
> > > > > >> > > > > allows access to the underlying node of the class.
> > > > > >> > > > >
> > > > > >> > > > > So I created a separate namespace for the meta meta
> > classes
> > > > and added the
> > > > > >> > > > > following three definitions:
> > > > > >> > > > >
> > > > > >> > > > > val tagName = metaNamespace.getMetaProperty("tagname",
> > true)
> > > > > >> > > > > tagName.setCardinality(1)
> > > > > >> > > > > val taggable = metaNamespace.getMetaClass("taggable",
> > true)
> > > > > >> > > > >
> > > > > >> > > > > body.node.setProperty("tagname", "body")
> > > > > >> > > > >
> > > > > >> > > > > This creates a property "tagname" with the value "body"
> > for
> > > > the class named
> > > > > >> > > > > "body".
> > > > > >> > > > >
> > > > > >> > > > > Now comes the more ambiguous part, how to link "body" to
> > > > "taggable".
> > > > > >> > > > >
> > > > > >> > > > > I can make body.node an instance of taggable. Once there
> > is a
> > > > validator,
> > > > > >> > > > > the existence of a "tagname" property with cardinality 1
> > > > should be checked,
> > > > > >> > > > > so it is reasonable to make body.node an instance of
> > taggable.
> > > > > >> > > > >
> > > > > >> > > > > At the same time the class body is actually a subclass of
> > > > taggable, so I am
> > > > > >> > > > > inclined to define that as well.
> > > > > >> > > > >
> > > > > >> > > > > So I end up doing the following:
> > > > > >> > > > >
> > > > > >> > > > > taggable.getDirectInstances.add(body.node)
> > > > > >> > > > > taggable.getDirectSubs.add(body)
> > > > > >> > > > >
> > > > > >> > > > > I would like to know if this is the correct approach to
> > this
> > > > situation, or
> > > > > >> > > > > whether there are better alternatives.
> > > > > >> > > > >
> > > > > >> > > > > Kind regards,
> > > > > >> > > > > Niels Hoogeveen
> > > > > >> > > > >
> > > > > >> > > > >
> > > > > >> > > > >
> > > > _________________________________________________________________
> > > > > >> > > > > New Windows 7: Find the right PC for you. Learn more.
> > > > > >> > > > > http://windows.microsoft.com/shop
> > > > > >> > > > > _______________________________________________
> > > > > >> > > > > Neo mailing list
> > > > > >> > > > > User@lists.neo4j.org
> > > > > >> > > > > https://lists.neo4j.org/mailman/listinfo/user
> > > > > >> > > > >
> > > > > >> > > >
> > > > > >> > > >
> > > > > >> > > >
> > > > > >> > > > --
> > > > > >> > > > Mattias Persson, [matt...@neotechnology.com]
> > > > > >> > > > Neo Technology, www.neotechnology.com
> > > > > >> > > > _______________________________________________
> > > > > >> > > > Neo mailing list
> > > > > >> > > > User@lists.neo4j.org
> > > > > >> > > > https://lists.neo4j.org/mailman/listinfo/user
> > > > > >> > >
> > > > > >> > >
> > _________________________________________________________________
> > > > > >> > > Express yourself instantly with MSN Messenger! Download today
> > it's
> > > > FREE!
> > > > > >> > >
> > http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
> > > > > >> > > _______________________________________________
> > > > > >> > > Neo mailing list
> > > > > >> > > User@lists.neo4j.org
> > > > > >> > > https://lists.neo4j.org/mailman/listinfo/user
> > > > > >> >
> > > > > >> >
> > _________________________________________________________________
> > > > > >> > New Windows 7: Find the right PC for you. Learn more.
> > > > > >> > http://windows.microsoft.com/shop
> > > > > >> > _______________________________________________
> > > > > >> > Neo mailing list
> > > > > >> > User@lists.neo4j.org
> > > > > >> > https://lists.neo4j.org/mailman/listinfo/user
> > > > > >>
> > > > > >> _________________________________________________________________
> > > > > >> New Windows 7: Find the right PC for you. Learn more.
> > > > > >> http://windows.microsoft.com/shop
> > > > > >> _______________________________________________
> > > > > >> Neo mailing list
> > > > > >> User@lists.neo4j.org
> > > > > >> https://lists.neo4j.org/mailman/listinfo/user
> > > > > >> _______________________________________________
> > > > > >> Neo mailing list
> > > > > >> User@lists.neo4j.org
> > > > > >> https://lists.neo4j.org/mailman/listinfo/user
> > > > > >
> > > > > > _________________________________________________________________
> > > > > > New Windows 7: Find the right PC for you. Learn more.
> > > > > > http://windows.microsoft.com/shop
> > > > > > _______________________________________________
> > > > > > Neo mailing list
> > > > > > User@lists.neo4j.org
> > > > > > https://lists.neo4j.org/mailman/listinfo/user
> > > > > >
> > > > > _______________________________________________
> > > > > Neo mailing list
> > > > > User@lists.neo4j.org
> > > > > https://lists.neo4j.org/mailman/listinfo/user
> > > >
> > > > _________________________________________________________________
> > > > Express yourself instantly with MSN Messenger! Download today it's
> > FREE!
> > > > http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
> > > > _______________________________________________
> > > > Neo mailing list
> > > > User@lists.neo4j.org
> > > > https://lists.neo4j.org/mailman/listinfo/user
> > > >
> > >
> > >
> > >
> > > --
> > > Mattias Persson, [matt...@neotechnology.com]
> > > Neo Technology, www.neotechnology.com
> > > _______________________________________________
> > > Neo mailing list
> > > User@lists.neo4j.org
> > > https://lists.neo4j.org/mailman/listinfo/user
> >
> > _________________________________________________________________
> > Express yourself instantly with MSN Messenger! Download today it's FREE!
> > http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
> > _______________________________________________
> > Neo mailing list
> > User@lists.neo4j.org
> > https://lists.neo4j.org/mailman/listinfo/user
> >
> 
> 
> 
> -- 
> Mattias Persson, [matt...@neotechnology.com]
> Hacker, Neo Technology
> www.neotechnology.com
> _______________________________________________
> Neo mailing list
> User@lists.neo4j.org
> https://lists.neo4j.org/mailman/listinfo/user
                                          
_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE!
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
_______________________________________________
Neo mailing list
User@lists.neo4j.org
https://lists.neo4j.org/mailman/listinfo/user

Reply via email to