[Data-modeling] "Mentions" and "Mentioned In" - locked down types and community

brendan brendan at metaweb.com
Fri Feb 13 23:26:03 UTC 2009


You can also create new types and create properties that are delegated  
from existing types through the freebase.com UI, as well.  Delegating  
to or from a compound value type (CVT) property is not supported,  
though, so this pattern has it's limits. It's basically for creating  
types that extend existing types.  Schema versioning and backward  
compatibility (a great idea) might be possible if a more sophisticated  
"translation" system were available. e.g. A common refactoring pattern  
is: a simple property that should be a CVT to reflect more rich  
assertions.

There are, however, some cases where types will just end up competing  
with each other resulting in de-normalization: lots of redundant,  
fragmented, incomplete data.  To borrow a recent example from this  
email list:  If I decided that the book type really should have a  
single ISBN property that allowed either ISBN-10 or ISBN-13 numbers to  
be entered and the book domain admin insisted that there should be two  
distinct properties, for example... I may feel compelled to just  
create my own book type and "compete" with the official type.  Not so  
good.

That particular example can (and will be) ironed out through community  
discourse.  It's not that contentious.  I acknowledge that there will  
be more difficult examples to come.  I guess it's fair to say the  
current model is: negotiate with the admins, compromise else go ahead  
and create your own type and live with the de-normalization.

Of course, the existence of public types administered by small numbers  
of people (some of them Metaweb employees) has it's issues. It calls  
for open-ness and responsibilty on the part of the admins, for sure.   
I'm not sure what alternative would work better.  I do think some kind  
of schema versioning with backward compatibility would be really  
helpful.

Brendan


On Feb 13, 2009, at 2:23 PM, Scott Meyer wrote:

> spencer kelly wrote:
>
>> I'm speaking about locked types- that a type I make will not be
>> developed in structure by anyone but me- and whose format is limited
>> by my particular effort and understanding.
>>
>> Indeed the whole point of freebase is to develop a collaborative
>> network, and this has been achieved in every ounce on the technology
>> side, but how often have you run into duplicate types, or tried to
>> reciprocate a type whose creator has vanished and hasn't logged in  
>> for
>> months? What will happen when we all die? The reason for schema
>> lockdown is to provide stable properties for developers. Which  
>> (though
>> I'm prepared'o be wrong) could be achieved by freezing a freebase 1.0
>> and then loosening up types in our live version.  Default
>> zero-permission types are the most un-wiki part of the freebase, a
>> glaring contrast to the crowd-source model on which it has chosen to
>> be built.
>
> One of the reasons for the lock down is indeed to provide
> a stable interface for application developers.  As the key
> distinction between a database and a wiki is applications,
> this is important.
>
> However, this isn't the primary reason.  The primary reason is
> that we need to preserve equality of effort. My 5 minutes should be
> worth no more than your five minutes.  If we allow unrestricted
> modification of types, we have a problem in that the person modifying
> the type, can, in a single operation, scrap the work of thousands
> of other people.
>
> So what to do when you want to modify a type and you don't have
> permissions?  Create your own type and use property delegation
> to borrow whatever properties you want from type you lack permissions
> to modify.  Delegating a property causes the types to share the
> same property so your type will have all the data from the donor type.
>
> I've attached some basic python code which demonstrates type
> creation and property delegation.  When doing complex type surgery,
> the best procedure that I've found is to write a python program
> which does what you want, debug the program against sandbox
> and then when all is working as desired, make the changes in
> freebase.
>
> Kind Regards,
>
> -Scott
>
>
> import simplejson
> import urllib
> from freebase.api import HTTPMetawebSession, MetawebError
>
> mss = HTTPMetawebSession( 'sandbox.freebase.com', 'your-account',  
> 'your-password' )
> mss.login()
>
> def key_exists( s, k ):
>    q = {
>        "id" : k,
>        "guid" : None }
>    return not None == s.mqlread( q )
>
> def create_type( s, name, key, ns, cvt=None, tip=None ):
>    if key_exists( s, ns + "/" + key ):
>        return
>    q = {
>        "create" : "unconditional",
>        "type" : "/type/type",
>        "/type/type/domain" : { "connect" : "insert", "id" : ns },
>        "name" : {"connect" : "insert", "value" : name, "lang" : "/ 
> lang/en" },
>        "key" : {
>            "connect" : "insert",
>            "value" : key,
>            "namespace" : ns }}
>    if cvt:
>        q['/freebase/type_hints/mediator'] = { "connect" : "update",  
> "value" : True }
>    if tip:
>        q['/freebase/documented_object/tip'] = { "connect" :  
> "update", "value" : tip, "lang" : "/lang/en" }
>    s.mqlwrite( q )
>
> def create_property( s, name, key, type, ect, unique,  
> disambig=False, tip=None, extra=None ):
>    if key_exists( s, type + "/" + key ):
>        return
>    q = {
>        "create" : "unconditional",
>        "type" : "/type/property",
>        "name" : name,
>        "key" : {
>            "connect" : "insert",
>            "value" : key,
>            "namespace" : type },
>        "schema" : { "connect" : "insert", "id" : type },
>        "expected_type" : { "connect" : "insert", "id" : ect },
>        "unique" : { "connect" : "update", "value" : unique }}
>    if tip:
>        q['/freebase/documented_object/tip'] = { "connect" :  
> "update", "value" : tip, "lang" : "/lang/en" }
>    if disambig:
>        q['/freebase/property_hints/disambiguator'] = { "connect" :  
> "update", "value" : True }
>    if extra:
>        q.update( extra )
>    s.mqlwrite( q )
>
> def delegate_property( s, p, type, ect=None ):
>    q = {
>        "id" : p,
>        "type" : "/type/property",
>        "name" : None,
>        "unique" : None,
>        "expected_type" : None,
>        "key" : None,
>        "/freebase/documented_object/tip" : None,
>        "/freebase/property_hints/disambiguator" : None }
>    r = s.mqlread( q )
>    if not ect:
>        ect = r["expected_type"]
>    create_property( s, r["name"], r["key"], type, ect, r["unique"],
>        r["/freebase/property_hints/disambiguator"],
>        r["/freebase/documented_object/tip"],
>        { "/type/property/delegated" : p } )
>
> def reciprocate_property( s, rp, name, key, type, unique,  
> disambig=False, tip=None, extra=None ):
>    q = {
>        "id" : rp,
>        "/type/property/expected_type" : None }
>    r = s.mqlread( q )
>    ect = r["/type/property/expected_type"]
>    create_property( s, name, key, type, ect, unique, disambig, tip,
>        { "/type/property/master_property" : rp } )
>
> def make_subclass( s, sub, super ):
>    q = {
>        "id" : super,
>        "type" : "/type/type",
>        "properties" : [{"id" : None}] }
>    r = s.mqlread( q )
>    for p in map( lambda( x ): x['id'], r['properties'] ):
>        delegate_property( s, p, sub )
>    w = {
>        "id" : sub,
>        "/freebase/type_hints/included_types" : { "connect" :  
> "insert", "id" : super }}
>    s.mqlwrite( w )
>
> _______________________________________________
> Data-modeling mailing list
> Data-modeling at freebase.com
> http://lists.freebase.com/mailman/listinfo/data-modeling



More information about the Data-modeling mailing list