{"id":829,"date":"2012-03-04T13:07:16","date_gmt":"2012-03-04T13:07:16","guid":{"rendered":"http:\/\/blog.soton.ac.uk\/webteam\/?p=829"},"modified":"2012-03-04T13:07:16","modified_gmt":"2012-03-04T13:07:16","slug":"all-of-type-x-an-antipattern","status":"publish","type":"post","link":"https:\/\/blog.soton.ac.uk\/webteam\/2012\/03\/04\/all-of-type-x-an-antipattern\/","title":{"rendered":"All-Things-Of-Type-X an Anti-pattern?"},"content":{"rendered":"<p>When I was developing the <a href=\"http:\/\/graphite.ecs.soton.ac.uk\/\">Graphite PHP Library<\/a> I added a simple function called $graph-&gt;allOfType( $type ) which would return a list of all the things of a given type in the current graph. For example the list of all foaf:Person or all Buildings.<\/p>\n<p>It&#8217;s also very tempting to do this when presented with a SPARQL endpoint, and a totally legitimate thing to do when exploring the data.<\/p>\n<h2>However&#8230;<\/h2>\n<p>Leaving applications lying around which use this either as SPARQL or otherwise is a ticking time bomb. Here&#8217;s an example;<\/p>\n<p>At the university, I&#8217;ve got a list of all the buildings, in our endpoint. So I cat get all our buildings by doing this query:<\/p>\n<p>(Note that rooms: is just a prefix for a vocabulary to describe rooms and buildings, sorry if that&#8217;s confusing)<\/p>\n<pre><a href=\"http:\/\/sparql.data.southampton.ac.uk\/?query=SELECT+%3Fthing+WHERE+{%0D%0A++%3Fthing+a+%3Chttp%3A%2F%2Fvocab.deri.ie%2Frooms%23Building%3E+.%0D%0A}%0D%0A&amp;output=htmltab&amp;jsonp=&amp;show_inline=1#results_table\">SELECT ?thing WHERE { ?thing a rooms:Building . }<\/a><\/pre>\n<p>OK, that&#8217;s great. But as our system has grown we&#8217;ve now got some buildings which are in the data but no longer part of the university state, and I&#8217;d like to add some buildings which are in the city, but I can&#8217;t because my stupid naieve coding will assume all buildings in the store are our buildings.<\/p>\n<h2>Easily Solved<\/h2>\n<p>The solution is to add some semantics to say what I really mean, which is to have a list of buildings which are occupied by the university of southampton.\u00a0 I guess I just need to add<\/p>\n<pre>  &lt;http:\/\/id.southampton.ac.uk\/building\/32&gt; &lt;http:\/\/vocab.deri.ie\/rooms#occupant&gt; &lt;http:\/\/id.southampton.ac.uk\/&gt; .\r\n<\/pre>\n<p>(That last URI is the identifier for the university). Then the question becomes:<\/p>\n<pre>SELECT ?thing WHERE { \r\n   ?thing a rooms:Building . \r\n   ?thing rooms:occupant &lt;http:\/\/id.southampton.ac.uk\/&gt; .\r\n}\r\n<\/pre>\n<p>Which is a tiny bit more work, but much more future-proof.<\/p>\n<h2>App Builders are Lazy<\/h2>\n<p>Well, I am. So people will only do just enough to work. The first version of an app may well use naive solutions of the all-things-of-type-X pattern, as it&#8217;ll solve their immediate problem. When it starts to break, they&#8217;ll look for a new pattern and so it&#8217;d be good if data providers made sure there&#8217;s solid triples giving these simple facts.<\/p>\n<p>There&#8217;s a really cheap-and-cheerful alternate solution, which is to solve the problem at the &#8216;graph&#8217; level. ie. state that all the buildings in triples you get from &lt;<a href=\"http:\/\/id.southampton.ac.uk\/dataset\/places\/latest\">http:\/\/id.southampton.ac.uk\/dataset\/places\/latest<\/a>&gt; have certain properties. This is handy for hacking, but lousy for data aggregation.<\/p>\n<p>This came about as I was thinking about making a version of my <a href=\"http:\/\/maps.southampton.ac.uk\/service\/?src=http:\/\/id.southampton.ac.uk\/dataset\/places\/latest\">building finder web-app<\/a> which would aggregate together buildings from Southampton, Oxford &amp; Lincoln. I realised <a href=\"http:\/\/maps.southampton.ac.uk\/service\/?src=http%3A%2F%2Fgraphite.ecs.soton.ac.uk%2Fexamples\/uni-buildings.rdf\">I could easily do that<\/a>, but it doesn&#8217;t give me a way to indicate who each building belongs to as the assumption breaks down when we merge the data.<\/p>\n<p>In the short term, there&#8217;s some value in aggreeing that an App accepts a target RDF URL, and should show everything it understands. If there&#8217;s a SPARQL endpoint then maybe the owners need to write a CONSTRUCT query to give that app what it needs. This isn&#8217;t an ideal solution, but it works.<\/p>\n<p>I think right now it&#8217;s just important for us to notice what assumptions we make. RDF &amp; SPARQL are not like Tables &amp; SQL. There&#8217;s some new techniques to learn&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When I was developing the Graphite PHP Library I added a simple function called $graph-&gt;allOfType( $type ) which would return a list of all the things of a given type in the current graph. For example the list of all foaf:Person or all Buildings. It&#8217;s also very tempting to do this when presented with a [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[198,136],"tags":[],"class_list":["post-829","post","type-post","status-publish","format-standard","hentry","category-best-practice","category-rdf"],"_links":{"self":[{"href":"https:\/\/blog.soton.ac.uk\/webteam\/wp-json\/wp\/v2\/posts\/829","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.soton.ac.uk\/webteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.soton.ac.uk\/webteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.soton.ac.uk\/webteam\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.soton.ac.uk\/webteam\/wp-json\/wp\/v2\/comments?post=829"}],"version-history":[{"count":1,"href":"https:\/\/blog.soton.ac.uk\/webteam\/wp-json\/wp\/v2\/posts\/829\/revisions"}],"predecessor-version":[{"id":830,"href":"https:\/\/blog.soton.ac.uk\/webteam\/wp-json\/wp\/v2\/posts\/829\/revisions\/830"}],"wp:attachment":[{"href":"https:\/\/blog.soton.ac.uk\/webteam\/wp-json\/wp\/v2\/media?parent=829"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.soton.ac.uk\/webteam\/wp-json\/wp\/v2\/categories?post=829"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.soton.ac.uk\/webteam\/wp-json\/wp\/v2\/tags?post=829"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}