[Data-modeling] Cross referencing data within CVTs?
Scott Meyer
sm at metaweb.com
Mon Dec 15 20:29:55 UTC 2008
Ed Laurent wrote:
> I'm interested in cross referencing data within CVTs. Is this possible,
> pehaps through the use of delegated properties? For example, I want to
> create a list of taxa that are designated as priorities within locations
> as specified in a written work (i.e., "priority taxa"&"priority
> location" as a property of "priority source") and cross reference it
> with lists on the taxa and location types (i.e., "priority
> taxa"&"priority source" as a property of "priority location", and
> "priority location"&"priority source" as a property of "priority taxa")
> so that all three lists are populated when any one of them is filled in.
> I can't figure out how to do this. Is it possible?
It is if you do the cross referencing through the same CVT. What we need
in order to accomplish this is for the same property to be shared between
several types. Our current delegation mechanism will do the trick but the
UI is still a bit cumbersome. If I understand your situation, you have
three properties, a, b, and c, and you want to three cvt types with
properties (a, b), (b, c), and (c, a). The basic recipe to achieve this
is to create some base type to hold the original properties, then create
the three types you want, then delegate the desired properties to each.
The CVT's you create are co-typed with one or more of your types, and,
due to property-delegation populating one property, populates it for
all co-types.
But, the properties must share a CVT instance. If you have to create
separate CVTs, the fact that we share properties at the CVT-level is
nice (in the sense that we've avoided creating a bunch of redundant
typeguids) but you'll never get the auto-population effect.
As I've just worked through this in a different context, here's some
python code which automates the process a bit by copying property
names, tips, etc. from the source property. Note that delegation
of master and reverse properties is a bit odd:
master <---- reverse
^ ^
| |
| |
del master del reverse
The delegate master is not the reverse of the delegate reverse. Sorry.
Yes, we're planning on fixing that.
-Scott
import simplejson
import urllib
from freebase.api import HTTPMetawebSession, MetawebError
mss = HTTPMetawebSession( 'sandbox.freebase.com', 'your-account', 'your-password' )
mss.login()
# Check to see if a key exists. If this is just you hacking on your schema,
# this is sufficient to make operations idempotent.
def key_exists( s, k ):
q = {
"id" : k,
"guid" : None }
return not None == s.mqlread( 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 )
# Delegate a property. We copy as much as possible from the source property
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 } )
More information about the Data-modeling
mailing list