Ken
Introduction
Ken is a Data Layer for Knowledge Representation.
It’s being built to access the Metaweb Services supplied by Freebase.com. Just born, the project’s goals are the provision of a concise API for querying and writing. Therefore it wraps the Metaweb Architecture to smart Ruby Objects.
You can navigate the Freebase Graph using a rubyish syntax.
If things go right, you should be able to use this library as a Data Layer (instead of or in addition to ActiveRecord/DataMapper) for your Web Framework of choice (Merb, Rails).
Installation
Use GitHub RubyGems.
$ gem sources -a http://gems.github.com (you only have to do this once)
$ sudo gem install michael-ken
Or even better, stay on The Edge.
Getting started
The first place to get started with Freebase is of course, Freebase. Try out their Browser at http://www.freebase.com.
The Freebase Database can be thought of as a huge graph of interconnected nodes that represent knowledge (in a much more structured way than wikipedia does). That graph can be viewed at a higher level through an object-oriented lens which leads to easier interaction. To understand the fundamental Metaweb Architecture please read the official MQL Reference guide (with focus on Chapter 2) provided by Freebase.
In addition, you can learn a lot by employing the Freebase Query Editor.
Fetching a Resource
Let’s ask Ken what he knows about the British Band New Order.
resource = Ken.get('/en/new_order') # => <Resource id="/en/new_order" name="New Order">
Inspecting the Types
Every Resource can have multiple types.
resource.types
# => [ #<Type id="/film/music_contributor" name="Film music contributor">, #<Type id="/music/artist" name="Musical Artist">,
#<Type id="/common/topic" name="Topic">, #<Type id="/music/musical_group" name="Musical Group">,
#<Type id="/broadcast/artist" name="Broadcast Artist">, #<Type id="/music/group_member" name="Musical Group Member"> ]
We can see that New Order is a member of Music Artist, Film Music Contributor, Broadcast Artist and other types.
Inspecting a Type’s properties
A type defines a set of properties to describe a Resource.
resource.types.each do |type|
type.properties # => e.g. [ #<Property id="/music/musical_group/member"> ]
end
We get sets of Properties for each Type. The Type Musical Group has just one Property /music/musical_group/member
named Members Of Musical Group.
Listing all Attributes
After inspecting a Resource’s Types and Properties we now know what we could know. But actually we don’t know nothing :) So it’s time to ask for the values of properties, the so called Attributes.
Note: In Ken’s terminology we differ between Properties and concrete Property instances, the Attributes, while Freebase itself doesn’t.
resource.attributes.each do |att|
att # => e.g. #<Attribute property="/music/artist/album">
att.property.name # => e.g. "Albums"
att.values
# e.g. => [ #<Resource id="/guid/9202a8c04000641f8000000002fa2556" name="Ceremony">,
#<Resource id="/guid/9202a8c04000641f8000000002fa24d5" name="Procession">,
#<Resource id="/guid/9202a8c04000641f8000000002fa20d3" name="Everything's Gone Green">, ... ]
# e.g. => ["1980"]
end
Attributes are slightly more complicated to handle compared to Types and Properties.
There are four kinds of Attributes.
- Unique Value Type
- Unique Object Type
- Non-unique Value Type
- Non-unique Object
In order to be able to use unique and non-unique Attributes in the same manner we always wrap the value of an Attribute in a Collection, no matter if there’s one value or there are many.
Group Attributes by their Type using Views
resource.views.each do |view|
view # => e.g. #<View type="/music/artist">
view.type # => e.g #<Type id="/music/artist" name="Musical Artist">
view.attributes
# => [#<Attribute property="/music/artist/home_page">, #<Attribute property="/music/artist/genre">,
#<Attribute property="/music/artist/active_start">, #<Attribute property="/music/artist/similar_artist">,
#<Attribute property="/music/artist/album">, #<Attribute property="/music/artist/label">,
#<Attribute property="/music/artist/track">, #<Attribute property="/music/artist/origin">]
view.attributes.each do |att|
att.values
# e.g. => [ #<Resource id="/en/alternative_dance" name="Alternative dance">,
#<Resource id="/en/synthpop" name="Synthpop">,
#<Resource id="/en/house_music" name="House music">,
#<Resource id="/en/post-punk" name="Post-punk"> ]
# e.g. => ["1980"]
end
end
Fetching multiple Resources using a query
As of now you can ask for multiple Resources by specifying a query.
resources = Ken.all(:name => "Apple", :type => "/music/album")
# => [#<Resource id="/guid/9202a8c04000641f80000000031dae7c" name="Apple">,
#<Resource id="/guid/9202a8c04000641f8000000007ce31ec" name="Apple">]
Keep in mind that only the top level of the query is mapped to a Collection of Resource Objects. So asking for values in a nested level does not make sense. Use nested statements just for lowering the top level result.
However you can instead navigate the normal way to figure out that values. But won’t that require another query to triggered? Doubtful.
Let’s look at a nested query:
query = {
:directed_by => "George Lucas",
:starring => [
{
:actor => "Harrison Ford"
}
],
:type => "/film/film"
}
resources = Ken.all(query)
# => [#<Resource id="/en/star_wars_episode_iv_a_new_hope" name="Star Wars Episode IV: A New Hope">,
#<Resource id="/en/american_graffiti" name="American Graffiti">,
#<Resource id="/en/the_star_wars_holiday_special" name="The Star Wars Holiday Special">]
Status
Currently, the focus lies on inspecting Freebase Resources in a generic way. That’s why there is no support for accessing Properties or Attributes directly when you know them already. That keeps me focussed and prevents me from adding too much sugar.
Therefore I would say that the first application using Ken will definitely be a Browser Application. :)
If you rather want to query based on Types and access Properties/Attributes directly you should consider using Chris Eppsteins Freebase Library instead.
Features
- Fetching of single Resources
- Fetching of multiple Resources by specifying a query
- Type inspection
- Attributes inspection
- Views on Resources to group Attributes based on the Resource’s types
- Some specs
Roadmap
- Much more specs
- Better Type Support
- API for Set Based Browsing (see http://mqlx.com/~david/parallax/)
- Accessing Properties/Attributes directly (e.g. resource.genres )
- Write-Support
Initial thoughts, obviously not up-to-date and not conforming to the current version, are available at http://wiki.github.com/michael/ken.