CINXE.COM

Steve Baskauf's blog: February 2017

<!DOCTYPE html> <html class='v2' dir='ltr' lang='en'> <head> <link href='https://www.blogger.com/static/v1/widgets/3566091532-css_bundle_v2.css' rel='stylesheet' type='text/css'/> <meta content='width=1100' name='viewport'/> <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/> <meta content='blogger' name='generator'/> <link href='http://baskauf.blogspot.com/favicon.ico' rel='icon' type='image/x-icon'/> <link href='http://baskauf.blogspot.com/2017/02/' rel='canonical'/> <link rel="alternate" type="application/atom+xml" title="Steve Baskauf&#39;s blog - Atom" href="http://baskauf.blogspot.com/feeds/posts/default" /> <link rel="alternate" type="application/rss+xml" title="Steve Baskauf&#39;s blog - RSS" href="http://baskauf.blogspot.com/feeds/posts/default?alt=rss" /> <link rel="service.post" type="application/atom+xml" title="Steve Baskauf&#39;s blog - Atom" href="https://www.blogger.com/feeds/5299754536670281996/posts/default" /> <!--Can't find substitution for tag [blog.ieCssRetrofitLinks]--> <meta content='http://baskauf.blogspot.com/2017/02/' property='og:url'/> <meta content='Steve Baskauf&#39;s blog' property='og:title'/> <meta content='' property='og:description'/> <title>Steve Baskauf's blog: February 2017</title> <style id='page-skin-1' type='text/css'><!-- /* ----------------------------------------------- Blogger Template Style Name: Simple Designer: Blogger URL: www.blogger.com ----------------------------------------------- */ /* Content ----------------------------------------------- */ body { font: normal normal 12px 'Trebuchet MS', Trebuchet, Verdana, sans-serif; color: #666666; background: #ffffff none repeat scroll top left; padding: 0 0 0 0; } html body .region-inner { min-width: 0; max-width: 100%; width: auto; } h2 { font-size: 22px; } a:link { text-decoration:none; color: #8832ff; } a:visited { text-decoration:none; color: #bb2188; } a:hover { text-decoration:underline; color: #33aaff; } .body-fauxcolumn-outer .fauxcolumn-inner { background: transparent none repeat scroll top left; _background-image: none; } .body-fauxcolumn-outer .cap-top { position: absolute; z-index: 1; height: 400px; width: 100%; } .body-fauxcolumn-outer .cap-top .cap-left { width: 100%; background: transparent none repeat-x scroll top left; _background-image: none; } .content-outer { -moz-box-shadow: 0 0 0 rgba(0, 0, 0, .15); -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .15); -goog-ms-box-shadow: 0 0 0 #333333; box-shadow: 0 0 0 rgba(0, 0, 0, .15); margin-bottom: 1px; } .content-inner { padding: 10px 40px; } .content-inner { background-color: #ffffff; } /* Header ----------------------------------------------- */ .header-outer { background: transparent none repeat-x scroll 0 -400px; _background-image: none; } .Header h1 { font: normal normal 40px 'Trebuchet MS',Trebuchet,Verdana,sans-serif; color: #000000; text-shadow: 0 0 0 rgba(0, 0, 0, .2); } .Header h1 a { color: #000000; } .Header .description { font-size: 18px; color: #000000; } .header-inner .Header .titlewrapper { padding: 22px 0; } .header-inner .Header .descriptionwrapper { padding: 0 0; } /* Tabs ----------------------------------------------- */ .tabs-inner .section:first-child { border-top: 0 solid #dddddd; } .tabs-inner .section:first-child ul { margin-top: -1px; border-top: 1px solid #dddddd; border-left: 1px solid #dddddd; border-right: 1px solid #dddddd; } .tabs-inner .widget ul { background: transparent none repeat-x scroll 0 -800px; _background-image: none; border-bottom: 1px solid #dddddd; margin-top: 0; margin-left: -30px; margin-right: -30px; } .tabs-inner .widget li a { display: inline-block; padding: .6em 1em; font: normal normal 12px 'Trebuchet MS', Trebuchet, Verdana, sans-serif; color: #000000; border-left: 1px solid #ffffff; border-right: 1px solid #dddddd; } .tabs-inner .widget li:first-child a { border-left: none; } .tabs-inner .widget li.selected a, .tabs-inner .widget li a:hover { color: #000000; background-color: #eeeeee; text-decoration: none; } /* Columns ----------------------------------------------- */ .main-outer { border-top: 0 solid transparent; } .fauxcolumn-left-outer .fauxcolumn-inner { border-right: 1px solid transparent; } .fauxcolumn-right-outer .fauxcolumn-inner { border-left: 1px solid transparent; } /* Headings ----------------------------------------------- */ div.widget > h2, div.widget h2.title { margin: 0 0 1em 0; font: normal bold 11px 'Trebuchet MS',Trebuchet,Verdana,sans-serif; color: #000000; } /* Widgets ----------------------------------------------- */ .widget .zippy { color: #999999; text-shadow: 2px 2px 1px rgba(0, 0, 0, .1); } .widget .popular-posts ul { list-style: none; } /* Posts ----------------------------------------------- */ h2.date-header { font: normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif; } .date-header span { background-color: #bbbbbb; color: #ffffff; padding: 0.4em; letter-spacing: 3px; margin: inherit; } .main-inner { padding-top: 35px; padding-bottom: 65px; } .main-inner .column-center-inner { padding: 0 0; } .main-inner .column-center-inner .section { margin: 0 1em; } .post { margin: 0 0 45px 0; } h3.post-title, .comments h4 { font: normal normal 22px 'Trebuchet MS',Trebuchet,Verdana,sans-serif; margin: .75em 0 0; } .post-body { font-size: 110%; line-height: 1.4; position: relative; } .post-body img, .post-body .tr-caption-container, .Profile img, .Image img, .BlogList .item-thumbnail img { padding: 2px; background: #ffffff; border: 1px solid #eeeeee; -moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); } .post-body img, .post-body .tr-caption-container { padding: 5px; } .post-body .tr-caption-container { color: #666666; } .post-body .tr-caption-container img { padding: 0; background: transparent; border: none; -moz-box-shadow: 0 0 0 rgba(0, 0, 0, .1); -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .1); box-shadow: 0 0 0 rgba(0, 0, 0, .1); } .post-header { margin: 0 0 1.5em; line-height: 1.6; font-size: 90%; } .post-footer { margin: 20px -2px 0; padding: 5px 10px; color: #666666; background-color: #eeeeee; border-bottom: 1px solid #eeeeee; line-height: 1.6; font-size: 90%; } #comments .comment-author { padding-top: 1.5em; border-top: 1px solid transparent; background-position: 0 1.5em; } #comments .comment-author:first-child { padding-top: 0; border-top: none; } .avatar-image-container { margin: .2em 0 0; } #comments .avatar-image-container img { border: 1px solid #eeeeee; } /* Comments ----------------------------------------------- */ .comments .comments-content .icon.blog-author { background-repeat: no-repeat; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9sLFwMeCjjhcOMAAAD+SURBVDjLtZSvTgNBEIe/WRRnm3U8RC1neQdsm1zSBIU9VVF1FkUguQQsD9ITmD7ECZIJSE4OZo9stoVjC/zc7ky+zH9hXwVwDpTAWWLrgS3QAe8AZgaAJI5zYAmc8r0G4AHYHQKVwII8PZrZFsBFkeRCABYiMh9BRUhnSkPTNCtVXYXURi1FpBDgArj8QU1eVXUzfnjv7yP7kwu1mYrkWlU33vs1QNu2qU8pwN0UpKoqokjWwCztrMuBhEhmh8bD5UDqur75asbcX0BGUB9/HAMB+r32hznJgXy2v0sGLBcyAJ1EK3LFcbo1s91JeLwAbwGYu7TP/3ZGfnXYPgAVNngtqatUNgAAAABJRU5ErkJggg==); } .comments .comments-content .loadmore a { border-top: 1px solid #999999; border-bottom: 1px solid #999999; } .comments .comment-thread.inline-thread { background-color: #eeeeee; } .comments .continue { border-top: 2px solid #999999; } /* Accents ---------------------------------------------- */ .section-columns td.columns-cell { border-left: 1px solid transparent; } .blog-pager { background: transparent url(//www.blogblog.com/1kt/simple/paging_dot.png) repeat-x scroll top center; } .blog-pager-older-link, .home-link, .blog-pager-newer-link { background-color: #ffffff; padding: 5px; } .footer-outer { border-top: 1px dashed #bbbbbb; } /* Mobile ----------------------------------------------- */ body.mobile { background-size: auto; } .mobile .body-fauxcolumn-outer { background: transparent none repeat scroll top left; } .mobile .body-fauxcolumn-outer .cap-top { background-size: 100% auto; } .mobile .content-outer { -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, .15); box-shadow: 0 0 3px rgba(0, 0, 0, .15); } .mobile .tabs-inner .widget ul { margin-left: 0; margin-right: 0; } .mobile .post { margin: 0; } .mobile .main-inner .column-center-inner .section { margin: 0; } .mobile .date-header span { padding: 0.1em 10px; margin: 0 -10px; } .mobile h3.post-title { margin: 0; } .mobile .blog-pager { background: transparent none no-repeat scroll top center; } .mobile .footer-outer { border-top: none; } .mobile .main-inner, .mobile .footer-inner { background-color: #ffffff; } .mobile-index-contents { color: #666666; } .mobile-link-button { background-color: #8832ff; } .mobile-link-button a:link, .mobile-link-button a:visited { color: #ffffff; } .mobile .tabs-inner .section:first-child { border-top: none; } .mobile .tabs-inner .PageList .widget-content { background-color: #eeeeee; color: #000000; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; } .mobile .tabs-inner .PageList .widget-content .pagelist-arrow { border-left: 1px solid #dddddd; } --></style> <style id='template-skin-1' type='text/css'><!-- body { min-width: 960px; } .content-outer, .content-fauxcolumn-outer, .region-inner { min-width: 960px; max-width: 960px; _width: 960px; } .main-inner .columns { padding-left: 0px; padding-right: 190px; } .main-inner .fauxcolumn-center-outer { left: 0px; right: 190px; /* IE6 does not respect left and right together */ _width: expression(this.parentNode.offsetWidth - parseInt("0px") - parseInt("190px") + 'px'); } .main-inner .fauxcolumn-left-outer { width: 0px; } .main-inner .fauxcolumn-right-outer { width: 190px; } .main-inner .column-left-outer { width: 0px; right: 100%; margin-left: -0px; } .main-inner .column-right-outer { width: 190px; margin-right: -190px; } #layout { min-width: 0; } #layout .content-outer { min-width: 0; width: 800px; } #layout .region-inner { min-width: 0; width: auto; } body#layout div.add_widget { padding: 8px; } body#layout div.add_widget a { margin-left: 32px; } --></style> <link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=5299754536670281996&amp;zx=c15af2b1-340f-4045-9056-6672d38a79d7' media='none' onload='if(media!=&#39;all&#39;)media=&#39;all&#39;' rel='stylesheet'/><noscript><link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=5299754536670281996&amp;zx=c15af2b1-340f-4045-9056-6672d38a79d7' rel='stylesheet'/></noscript> <meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/> <meta name='google-adsense-platform-domain' content='blogspot.com'/> </head> <body class='loading variant-simplysimple'> <div class='navbar section' id='navbar' name='Navbar'><div class='widget Navbar' data-version='1' id='Navbar1'><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/platform.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar/5299754536670281996?origin\x3dhttp://baskauf.blogspot.com', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script><script type="text/javascript"> (function() { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = '//pagead2.googlesyndication.com/pagead/js/google_top_exp.js'; var head = document.getElementsByTagName('head')[0]; if (head) { head.appendChild(script); }})(); </script> </div></div> <div class='body-fauxcolumns'> <div class='fauxcolumn-outer body-fauxcolumn-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <div class='content'> <div class='content-fauxcolumns'> <div class='fauxcolumn-outer content-fauxcolumn-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <div class='content-outer'> <div class='content-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left content-fauxborder-left'> <div class='fauxborder-right content-fauxborder-right'></div> <div class='content-inner'> <header> <div class='header-outer'> <div class='header-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left header-fauxborder-left'> <div class='fauxborder-right header-fauxborder-right'></div> <div class='region-inner header-inner'> <div class='header section' id='header' name='Header'><div class='widget Header' data-version='1' id='Header1'> <div id='header-inner'> <div class='titlewrapper'> <h1 class='title'> <a href='http://baskauf.blogspot.com/'> Steve Baskauf's blog </a> </h1> </div> <div class='descriptionwrapper'> <p class='description'><span> </span></p> </div> </div> </div></div> </div> </div> <div class='header-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </header> <div class='tabs-outer'> <div class='tabs-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left tabs-fauxborder-left'> <div class='fauxborder-right tabs-fauxborder-right'></div> <div class='region-inner tabs-inner'> <div class='tabs no-items section' id='crosscol' name='Cross-Column'></div> <div class='tabs no-items section' id='crosscol-overflow' name='Cross-Column 2'></div> </div> </div> <div class='tabs-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='main-outer'> <div class='main-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left main-fauxborder-left'> <div class='fauxborder-right main-fauxborder-right'></div> <div class='region-inner main-inner'> <div class='columns fauxcolumns'> <div class='fauxcolumn-outer fauxcolumn-center-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='fauxcolumn-outer fauxcolumn-left-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='fauxcolumn-outer fauxcolumn-right-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <!-- corrects IE6 width calculation --> <div class='columns-inner'> <div class='column-center-outer'> <div class='column-center-inner'> <div class='main section' id='main' name='Main'><div class='widget Blog' data-version='1' id='Blog1'> <div class='blog-posts hfeed'> <div class="date-outer"> <h2 class='date-header'><span>Monday, February 13, 2017</span></h2> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYwGMg6_S9D0KOiAV1Pn9H9q1pZucaZBerF-YuEdTHR5EEXQZJGPqWD3Bs4Ye-ngQARvzJZCbCB9O3agBro_74aJb-fecbyL1RddDLNkQ4bXytxM8A04T-alzriwa28MOIwlFbBgqOO4k/s640/test-graphs.png' itemprop='image_url'/> <meta content='5299754536670281996' itemprop='blogId'/> <meta content='281309205955855307' itemprop='postId'/> <a name='281309205955855307'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='http://baskauf.blogspot.com/2017/02/sparql-weirdness-of-unnamed-graphs.html'>SPARQL: the weirdness of unnamed graphs</a> </h3> <div class='post-header'> <div class='post-header-line-1'></div> </div> <div class='post-body entry-content' id='post-body-281309205955855307' itemprop='description articleBody'> This post is of a rather technical nature and is directed at people who are serious about setting up and experimenting with the management of SPARQL endpoints. &nbsp;If you want to get <b>an abbreviated view</b>, you could probably read down through the "Graphs: named and otherwise" section, then skip down to "Names of unnamed graphs (review)" and read through the end. <br /> <br /> <h2> Background</h2> This semester, the focus of our <a href="https://heardlibrary.github.io/semantic-web/">Linked Data and Semantic Web working group</a>&nbsp;[1] at Vanderbilt has been to try to move from Linked Data in theory, to Linked Data in reality. &nbsp;Our main project has been to document the process of moving <a href="http://researchguides.library.vanderbilt.edu/prf.php?account_id=109576">Veronica Ikeshoji-Orlati</a>'s dataset on ancient vases <a href="https://github.com/HeardLibrary/semantic-web/blob/gh-pages/posts/2017-01-09.md">from spreadsheet to Linked Data dataset</a>. &nbsp;We have continued to make progress on moving <a href="https://as.vanderbilt.edu/historyart/people/miller.php">Tracy Miller</a>'s data on images of <a href="http://baskauf.blogspot.com/2016/11/sparql-based-web-app-to-find-chinese.html">Chinese temple architecture</a> from a test RDF graph to production. <br /> <br /> One of the remaining problems we have been facing is setting up a final production triplestore and SPARQL endpoing to host the RDF data that we are producing. &nbsp;The <a href="http://library.vanderbilt.edu/">Vanderbilt Heard Library</a> has maintained a <a href="http://callimachusproject.org/">Callimachus</a>-based SPARQL endpoint at&nbsp;<a href="http://rdf.library.vanderbilt.edu/">http://rdf.library.vanderbilt.edu/</a> since the completion of Sean King's <a href="http://library.vanderbilt.edu/about/fellows/fellowships/2015-bioimages-king.php">Dean's Fellow project</a> in 2015. &nbsp;But Callimachus has some serious deficiencies related to speed (see <a href="http://baskauf.blogspot.com/2016/02/stress-testing-stardog-reasoner.html">this post</a> for details) and we had been considering replacing it with a <a href="http://stardog.com/">Stardog</a>-based endpoint. &nbsp;However, the community version of Stardog has a limit of 25 million triples per database, and we could easily go over that by loading either the Getty Thesaurus of Geographic Names or the GeoNames dataset, both of which contain well over 100 million triples. &nbsp;So we have been considering using <a href="https://www.blazegraph.com/">Blazegraph</a>&nbsp;(the graph database used by <a href="https://www.wikidata.org/">Wikidata</a>), which has no triple limit. &nbsp;I have already <a href="http://baskauf.blogspot.com/2016/10/linked-data-magic-and-big-data.html">reported on my experience with loading 100+ million triples into Blazegraph in an earlier post</a>. &nbsp;One issue that became apparent to me through that exercise was that appropriate use of named graphs would be critical to effective maintenance of a production triplestore and SPARQL endpoint. It also became apparent that my understanding of RDF graphs in the context of SPARQL was too deficient to make further progress on this front. &nbsp;This post is a record of my attempt to remedy that problem.<br /> <br /> <h2> Assumptions</h2> This post assumes that you have a basic understanding of RDF, the Turtle serialization of RDF, and the SPARQL query language. &nbsp;There are many good sources of information about RDF in general - the <a href="https://www.w3.org/TR/rdf11-primer/">RDF 1.1 Primer</a> is a good place to start. &nbsp;For a good introduction to SPARQL, I recommend Bob DuCharme's <a href="http://www.learningsparql.com/">Learning SPARQL</a>. <br /> <br /> <br /> <div class="separator" style="clear: both; text-align: center;"> </div> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYwGMg6_S9D0KOiAV1Pn9H9q1pZucaZBerF-YuEdTHR5EEXQZJGPqWD3Bs4Ye-ngQARvzJZCbCB9O3agBro_74aJb-fecbyL1RddDLNkQ4bXytxM8A04T-alzriwa28MOIwlFbBgqOO4k/s1600/test-graphs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="398" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYwGMg6_S9D0KOiAV1Pn9H9q1pZucaZBerF-YuEdTHR5EEXQZJGPqWD3Bs4Ye-ngQARvzJZCbCB9O3agBro_74aJb-fecbyL1RddDLNkQ4bXytxM8A04T-alzriwa28MOIwlFbBgqOO4k/s640/test-graphs.png" width="640" /></a></div> <h2> Graphs: named and otherwise</h2> One of the impediments to understanding how graphs interact with SPARQL is understanding the terminology used in the SPARQL specification. &nbsp;Please bear with me as I define some of the important terms needed to talk about graphs in the context of SPARQL. &nbsp;The technical documentation defining these terms is the <a href="https://www.w3.org/TR/sparql11-query/#rdfDataset">SPARQL 1.1 Query Language W3C Recommendation, Section 13</a>.<br /> <br /> In the abstract sense, a graph defines the connections between entities, with the entities represented as nodes and the connections between them represented as arcs (also known as edges). &nbsp;The RDF data model is graph-based, and a graph in RDF is described by triples. &nbsp;Each triple describes the relationship between two nodes connected by an arc. &nbsp;Thus, in RDF a <b>graph</b> can be defined as <b>a set of triples</b>. <br /> <br /> I used three graphs for the tests I'll be describing in this post. &nbsp;The first graph contains 12 triples and describes the Chinese temple site Anchansi and some other things related to that site. &nbsp;The full graph in Turtle serialization can be obtained at <a href="https://gist.github.com/baskaufs/e171e2ed54b35fc5c86ca387b9b46ac8">this gist</a>, but two of the triples are shown in the diagram above. &nbsp;As with any other resource in RDF, a graph can be named by assigning it a URI. &nbsp;In this first graph, I've chosen not to assign it an identifying URI. &nbsp;I will refer to this graph as the "<b>unnamed graph</b>". <br /> <br /> The second graph contains 18 triples and describes the temple site Baitaisi. &nbsp;The graph in Turtle serialization is at <a href="https://gist.github.com/baskaufs/30a2720448276950ad106bbe3298963e">this gist</a>, and two triples from the graph are shown in the diagram above. &nbsp;I have chosen to name the second graph by assigning it the URI <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://tang-song/baitaisi&gt;</span>. &nbsp;You should note that although the URI denotes the graph, it isn't a URL that "does" something. &nbsp;There is no web page that will be loaded if you put the URI in a browser. &nbsp;That is totally fine - the URI is really just a name. &nbsp;I'll refer to this graph by its URI - it is an example of a <b>named graph</b>. <br /> <br /> A third graph about the Chinese temple site Baiyugong is <a href="https://gist.github.com/baskaufs/b92e5524ac042be6d635f3d83ed7c1da">here</a>. &nbsp;I'll refer to it from time to time by its URI&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://tang-song/baiyugong&gt;</span>.<br /> <br /> In the context of SPARQL, an RDF <b>dataset</b> is a <b>collection of graphs</b>. &nbsp;This collection of graphs will be loaded into some kind of data store (which I will refer to as a "triplestore"), where it can be queried using SPARQL. &nbsp;There may be many graphs in a triple store and SPARQL can query any or all of them.<br /> <br /> In a SPARQL query, the <b>default graph</b> is the set of triples that is queried by default when graph patterns in the query are not restricted to a particular named graph. &nbsp;There is always a default graph in an RDF dataset. &nbsp;However, that graph may include an unnamed graph, the merge of one or more named graphs, or it may be an empty graph (a graph containing no triples). <br /> <br /> A dataset may also include named graphs whose triples are searched exclusively when that graph is specified by name. <br /> <br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg13MMRXpmW6u1ztxDz6ZCNtvAJO1PRxr3fC4uPJDPccwqrMgG8nlfheQBmlmllDkwgAW5h5pJH8Jvaxr1T_hW4VOj3l_vuxXGDNU0R5K106pazcp-w4Oes_IgBJsrjA10ZpDJErkvYrPk/s1600/triplestores.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="124" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg13MMRXpmW6u1ztxDz6ZCNtvAJO1PRxr3fC4uPJDPccwqrMgG8nlfheQBmlmllDkwgAW5h5pJH8Jvaxr1T_hW4VOj3l_vuxXGDNU0R5K106pazcp-w4Oes_IgBJsrjA10ZpDJErkvYrPk/s640/triplestores.png" width="640" /></a></div> <br /> <h2> Aside on the three tested endpoints: setup and querying</h2> This section of the post is geared towards those who want to try any of these experiments themselves, who want to work towards setting up one of the three systems as a functioning triple store/SPARQL endpoint, or who just want to have a better understanding how the query interface works. &nbsp;If you don't care about any of those things, you can skip to the next section. <br /> <br /> Each of the three systems can be downloaded and set up for free. &nbsp;I believe that all three can be set up on Windows, Mac, and Linux, although I have only set them up on Windows. <br /> <br /> <b>Callimachus</b> can be downloaded from <a href="http://callimachusproject.org/get-started.xhtml?view">here</a> as a .zip bundle. &nbsp;After downloading, the <a href="http://callimachusproject.org/docs/1.5/getting-started-with-callimachus.docbook?view#Getting_Callimachus_Up_and_Running">Getting Started Guide</a> has straightforward installation instructions. &nbsp;After the setup script is complete, you will need to set up a local administrator account using a one-time URL. &nbsp;If the process fails, if you can't login, or if you destroy the installation (which I will tell you how to do later), you can delete the entire directory into which you unzipped the archive, unzip it again, and repeat the installation steps. &nbsp;You can't re-use the account setup URL a second time. <br /> <br /> To download <b>Stardog</b>, go to&nbsp;<a href="http://stardog.com/">http://stardog.com/</a> and click on the Download button. &nbsp;Unless you know you want to use the Enterprise version, select the Stardog Community version. &nbsp;Unfortunately, it has been a while since I installed Stardog, so I can't remember the details. &nbsp;However, I don't remember having any problems when I followed the <a href="https://docs.stardog.com/#_quick_start_guide">Quick Start Guide</a>. &nbsp;In order to avoid having to set the STARDOG_HOME environmental variable every time I wanted to use Stardog, I made the following batch file in my user directory:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">set STARDOG_HOME=C:\stardog-home</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">C:\stardog-4.0.3\bin\stardog-admin.bat server start</span><br /> <br /> where the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">stardog-4.0.3\bin</span> is the directory where the binaries were installed. &nbsp;To start the server, I just run this batch file from a command prompt. &nbsp;Stardog ships with a default superuser account "admin" with the password "admin", which is fine for testing on your local machine. <br /> <br /> To download <b>Blazegraph</b>, go to&nbsp;<a href="https://www.blazegraph.com/">https://www.blazegraph.com/</a> and click the download button. The executable is a Java .jar file that is invoked from the command line, so there is basically no installation required. &nbsp;Blazegraph has a <a href="https://wiki.blazegraph.com/wiki/index.php/Quick_Start">Quick Start</a>&nbsp;guide as a part of its wiki, although the wiki in general is somewhat minimal and does not have much in the way of examples. &nbsp;For convenience, I put the .jar file in my user directory and put that single command line into a batch file so that I can easily start Blazegraph by invoking the batch file. &nbsp;There isn't any user login required to use Blazegraph - read-only access is set up by settings in the installation. &nbsp;I've read about this on the <a href="https://sourceforge.net/p/bigdata/mailman/bigdata-developers/thread/CAEY4DnR6yXeecsMDpVwSu0hbVoKs7L5CeL9p0p57OigX%2Bc%2BHVw%40mail.gmail.com/#msg35117562">developer's email list</a>, but not really absorbed it.<br /> <br /> [Note added 2017-09-19: I had occasion to reinstall Blazegraph on another computer and was reminded of an issue that has to be resolved before Blazegraph will work on Windows (at least Win10). &nbsp;The issue is described <a href="https://sourceforge.net/p/bigdata/discussion/676946/thread/74643593/">on the developer's discussion list</a>. After running the first query or update, all subsequent queries or updates fail with a java.io.IOException error. &nbsp;The fix involves opening the blazegraph.jar file with an application that can open zip files (like 7zip). &nbsp;Extract the RWStore.properties configuration file and open it in a text editor. &nbsp;Add the line:<br /> <br /> com.bigdata.rwstore.RWStore.readBlobsAsync=false<br /> <br /> and save the file. &nbsp;Replace the old RWStore.properties file in the .jar file with the modified one and Blazegraph will work properly. &nbsp;Why this simple problem hasn't been fixed by the developers in the year since I last installed Blazegraph is beyond me. &nbsp;I guess most users don't install on Windows.]<br /> <br /> So what exactly is happening when you start up each of these applications from the command line? &nbsp;You'll get some kind of message saying that the software has started, but you won't get any kind of GUI interface to operate the software. &nbsp;That's because what you are actually doing is starting up a web server that is running on your local computer ("localhost"), and is not actually connected to any outside network. &nbsp;By default, each of the three applications allows you to access the local server endpoint through a different port (Callimachus = port 8080, Stardog = port 5820, and Blazegraph = port 9999), so you can run all three at once if you want. &nbsp;If you wanted to operate one of the applications as an external server, you would change the port to something else (probably port 80). <br /> <br /> So what does this mean? &nbsp;As with most other Web interactions, the communication with each of these localhost servers can take place through HTTP-mediated communication. &nbsp;SPARQL stands for "SPARQL Protocol and RDF Query Langage" - the "Protocol" part means that a part of the SPARQL Recommendation describes the language by which communication with the server takes place. &nbsp;The user sends a command via HTTP to the address of the server endpoint, coded using the SPARQL protocol and the server sends a response back to the user in the format (XML, JSON) that the user requests. &nbsp;If you enjoy such gory details, you can use cURL, Postman, or Advanced Rest Client to send raw queries to the localhost endpoint and then dissect the response to figure out what it means. &nbsp;Most people are are going to be <b>way</b> to lazy to do this for testing purposes. <br /> <br /> Because it's a pain to send and receive raw HTTP, each of the three platforms provides a web interface that mediates between the human and the endpoint. &nbsp;The web interface is a web form that allows the human user to type the query into a box, then click a button to send the query to the endpoint. &nbsp;The code in the web page properly encodes the query, sends it to the localhost endpoint, receives the response, then decodes the response into a tabular form that is easier for a human to visualize than XML or JSON. &nbsp;The web form makes it easy to interact with the endpoint for the purpose of developing and testing queries. <br /> <br /> However, when the endpoint is ultimately put into production, the sending of queries and visualization of the response would be handled not by a web form, but by Javascript in web pages that make it possible for the end users to interact with the endpoint using typical web controls like dropdowns and buttons without having to have any knowledge of writing queries. &nbsp;To see how this kind of interaction works, open the test Chinese Temple website at&nbsp;<a href="http://bioimages.vanderbilt.edu/tang-song.html">http://bioimages.vanderbilt.edu/tang-song.html</a>&nbsp;using Chrome. &nbsp;Click on the options button in the upper right corner of the browser and select "More tools" then "Developer tools". &nbsp;Click on the Network tab and you can watch how the web page interacts with the endpoint. &nbsp;Clicking on any of the "sparql?query=..." items, then the "header" tab on the right shows the queries that are being sent to the endpoint. &nbsp;Clicking on "response" tab on the right shows the response of the endpoint. &nbsp;This response is used by the Javascript in the web page to build the dropdown lists and the output at the bottom of the page.<br /> <br /> In the rest of this post, I will describe interactions with the localhost endpoint through the web form interface, but keep in mind that the same queries and commands that we type into the box could be sent directly to the endpoint from any other kind of application (Javascript in a web page, desktop application, smartphone app) that is capable of communicating using HTTP.<br /> <br /> <h2> Opening and using the web form interfaces</h2> Each of the three applications has a similar web form interface, although the exact behavior of each interface varies. &nbsp;There are actually two ways to interact with the server: through a SPARQL query (a read operation) and through a <a href="https://www.w3.org/TR/sparql11-update/">SPARQL Update</a> command (a write operation). &nbsp;The details of these two kinds of interactions are given for each of the applications.<br /> <h3> Callimachus</h3> To load the Callimachus web form interface after starting the server, paste the URL<br /> <br /> <a href="http://localhost:8080/sparql?view">http://localhost:8080/sparql?view</a><br /> <br /> into the browser address box. &nbsp;If everything is working, the Callimachus interface will look something like this:<br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2hc5KOTUkD_DLdQLUQ_CLTGRU1v2TiKLlkpp-JILrrxsQRP7PskI4MxcouvQJ9y2beeMG-kj6opQomHXpwz5r8sRyeGu-XvAACRYjobnhg_WsCwhhmxWylr1q7MPdwFlr2WOoGD3aI3o/s1600/callimachus-form-interface.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2hc5KOTUkD_DLdQLUQ_CLTGRU1v2TiKLlkpp-JILrrxsQRP7PskI4MxcouvQJ9y2beeMG-kj6opQomHXpwz5r8sRyeGu-XvAACRYjobnhg_WsCwhhmxWylr1q7MPdwFlr2WOoGD3aI3o/s640/callimachus-form-interface.png" width="640" /></a></div> <br /> Both queries and update commands are pasted into the same box. &nbsp;However, to make a query, you must click the "Evaluate Query" button. To give an update command, you must click the "Execute Update" button. &nbsp;After evaluating a query, you will be taken to another page where the response is displayed. &nbsp;Hitting the back button will take you back to the query page with the query still intact in the box. &nbsp;After executing an update, the orange button will "gray out" while the command is being executed and turn orange again when it is finished. &nbsp;No other indication is given that the command was executed.<br /> <br /> Namespace prefixes must be explicitly defined in the text of the box. &nbsp;However, once prefixes are used, Callimachus "remembers" them, so it isn't necessary to re-define them with every query.<br /> <br /> <h3> Stardog</h3> To load the Stardog web form interface after starting the server, paste the URL<br /> <br /> <a href="http://localhost:5820/myDB#!/query">http://localhost:5820/myDB#!/query</a><br /> <br /> into the browser address box. &nbsp;If everything is working, the Stardog interface will look something like this:<br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9omIjRsUpZvZVJ5KBzNRwxqtP6PHAdTurrgIGA7XbszHtwTj8jbpcpa_9hJD6XQtjLbU7SwPsC3V2jlI_i_VZbPpGlGChhOgLjrkjN_suoZrAjQHRO64I_HtJC48CE9XjhlSeKiiwCWo/s1600/stardog-form-interface.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="568" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9omIjRsUpZvZVJ5KBzNRwxqtP6PHAdTurrgIGA7XbszHtwTj8jbpcpa_9hJD6XQtjLbU7SwPsC3V2jlI_i_VZbPpGlGChhOgLjrkjN_suoZrAjQHRO64I_HtJC48CE9XjhlSeKiiwCWo/s640/stardog-form-interface.png" width="640" /></a></div> Stardog does not differentiate between queries and update commands. &nbsp;Both are typed into the same box and the "Execute" button is used to initiate both. &nbsp;Query results will be given in the "Results" area at the bottom of the screen. &nbsp;Successful update commands will display "True" in the Results area.<br /> <br /> Commonly used prefixes that appear in the Prefixes: box don't have to be explicitly typed in the text box. &nbsp;Additional pre-populated prefixes can be added in the Admin Console. <br /> <br /> <br /> <h3> Blazegraph</h3> To load the Blazegraph web form interface after starting the server, paste the URL<br /> <br /> <a href="http://localhost:9999/blazegraph/#query">http://localhost:9999/blazegraph/#query</a><br /> <br /> into the browser address box. &nbsp;If everything is working, the Blazegraph query interface will look something like this:<br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN-verzIIat88j_I3SNnKiDNI51FTvSCOZ-M4zo_FD0yaDZ1L6wHYO65T5KlpOrfoUTV0vy7-1Sxr6es1C04oZFiBXERRW7vFUXAq9XGhXJXt-Xv1RkwwvBlqne_FPnzNLV3m7vWdDa2Y/s1600/blazegraph-form-interface.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN-verzIIat88j_I3SNnKiDNI51FTvSCOZ-M4zo_FD0yaDZ1L6wHYO65T5KlpOrfoUTV0vy7-1Sxr6es1C04oZFiBXERRW7vFUXAq9XGhXJXt-Xv1RkwwvBlqne_FPnzNLV3m7vWdDa2Y/s640/blazegraph-form-interface.png" width="550" /></a></div> <br /> Only queries can be pasted into this box. &nbsp;Well-known namespace abbreviations can be inserted into the box using the "Namespace shortcuts" dropdowns above the box. &nbsp;If the query executes successfully, the results will show up in the space below the Execute button. &nbsp;The page also maintains a record of the past queries that have been run. &nbsp;They are hyperlinked, and clicking on them reloads the query in the box. <br /> <br /> To perform a SPARQL Update, the UPDATE tab must be selected. &nbsp;That generates a different web form that looks like this:<br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRnZbkMHnCVHO0Jh6cLpK-1dBwMSqplOtyj28hUssS57W9JjU4KxC9dBuCWymnMhZBt8OlAWjxaCEbhhX0_TJBVZHj9jKQA21WZWttLq8NXu7cyU5v2q0HCy3u_VRGrnxH8sitpHfpPZc/s1600/blazegraph-update-form-interface.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRnZbkMHnCVHO0Jh6cLpK-1dBwMSqplOtyj28hUssS57W9JjU4KxC9dBuCWymnMhZBt8OlAWjxaCEbhhX0_TJBVZHj9jKQA21WZWttLq8NXu7cyU5v2q0HCy3u_VRGrnxH8sitpHfpPZc/s640/blazegraph-update-form-interface.png" width="636" /></a></div> <br /> There are several ways to interact with this page. &nbsp;For now, the "Type:" dropdown should be set for "SPARQL Update". &nbsp;A successful update will show a COMMIT message at the bottom of the screen. &nbsp;The "mutationCount" gives an indication of the number of changes made; in this example 10 triples were added to the triplestore, so the mutationCount=10. <br /> <br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrzxnyAtgjT2Jim_Qkc3x_bH5egccVXhI6nWY0Nao7xnjgYnXEfdF9sFF4Sjf8ACPXJ91FYh5Qx9AtOGcx93Iu1hBHRn2GPINw8vQKJuoIk1jkKMaTpR4PqlJb3hVUYOpEqXD71awQsd4/s1600/mushroom.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrzxnyAtgjT2Jim_Qkc3x_bH5egccVXhI6nWY0Nao7xnjgYnXEfdF9sFF4Sjf8ACPXJ91FYh5Qx9AtOGcx93Iu1hBHRn2GPINw8vQKJuoIk1jkKMaTpR4PqlJb3hVUYOpEqXD71awQsd4/s320/mushroom.png" width="265" /></a></div> <br /> <h2> The SPARQL Update "nuclear option": DROP ALL</h2> One important question in any kind of experimentation is: "What do I do if I've totally screwed things up and I just want to start over?" &nbsp;In <b>Stardog</b> and <b>Blazegraph</b>, the answer is the SPARQL Update command "DROP ALL". &nbsp;Executing DROP ALL causes all of the triples in all of the graphs in the database to be deleted. &nbsp;You have a clean slate and an empty triplestore ready to start afresh. &nbsp;Obviously, you don't want to do this if you've spent hours loading hundreds of millions of triples into your production triplestore. &nbsp;But in the type of experiments I'm running here, it's a convenient way to clear things out for a new experiment. <br /> <br /> However, you <b><span style="color: red; font-size: large;">NEVER, NEVER, NEVER</span></b> want to issue this command in <b>Callimachus</b>. &nbsp;You will understand why later in this post, but for now I'll just say that the best case scenario is that you will be starting over with a clean install of Callimachus if you do it. &nbsp;Instead of DROP ALL, you should drop each graph individually. &nbsp;We will see how to do that below.<br /> <br /> <br /> <h2> Putting a graph into the triplestore (finally)</h2> All of these preliminaries were to get us to the point of being ready to load a graph into the triplestore. &nbsp;In each of the three applications, there are multiple ways to accomplish this task, and many of those ways differ among the applications. &nbsp;However, loading a graph using SPARQL Update works the same on all three (the beauty of W3C standards!), so that's how we will start. <br /> <br /> If you want to get try to achieve the same results as are shown in the examples here, save the three example files from my Gists: <a href="https://gist.github.com/baskaufs/30a2720448276950ad106bbe3298963e">test-baitaisi.ttl</a>, <a href="https://gist.github.com/baskaufs/b92e5524ac042be6d635f3d83ed7c1da">test-baiyugong.ttl</a>, and <a href="https://gist.github.com/baskaufs/e171e2ed54b35fc5c86ca387b9b46ac8">test-unnamed.ttl</a>. &nbsp;Put them somewhere on your hard drive where they will have a short and simple file path. <br /> <br /> Using the SPARQL Update web form of the application of your choice, type a command of this form:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: x-small;">LOAD &lt;file:///c:/Dropbox/tang-song/test-baitaisi.ttl&gt; INTO GRAPH &lt;http://tang-song/baitaisi&gt;</span><br /> <br /> This command contains two URIs within angle brackets. &nbsp;The second URI is the name that I want to use to denote the uploaded graph. &nbsp;I'll use that URI any time I want to refer to the graph in a query. &nbsp; Recall that this URI is just a name and doesn't have to actually represent any real URL on the Web. &nbsp;The first URI in the LOAD command is a URL - it provides the means to retrieve a file. &nbsp;It contains the path to the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">test-baitaisi.ttl</span> file that you downloaded (or some other file that contains serialized RDF). &nbsp;The triple slash thing after "<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">file:</span>" is kind of weird. &nbsp;The "host name" would typically go between the second and third slashes, but on your local computer it can be omitted - resulting in three slashes in a row. &nbsp;(I think you can actually use "<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">file://localhost/c:/</span>..." but I haven't tried it.) &nbsp;The path can't be relative, so in Windows, the full path starting with the drive letter must be given. &nbsp;I have not tried Mac and Linux, but see the answer to <a href="http://stackoverflow.com/questions/12711584/how-to-specify-a-local-file-within-html-using-the-file-scheme">this stackoverflow question</a> for probably path forms. &nbsp;If the path is wrong or the file doesn't exist, an error will be generated.<br /> <br /> Execute the update by clicking on the button. &nbsp;How do we know that the graph is actually there? &nbsp;Here is a SPARQL query that can answer the question:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">select distinct ?g where {&nbsp;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>graph ?g {</span><span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">?s ?p ?o</span><span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">}&nbsp;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">}</span><br /> <br /> If you are using Blazegraph, you'll have to switch from the Update tab to the Query tab before pasting the query into the box. &nbsp;Execute the query, and the results in Stardog and Blazegraph should show the URI that you used to name the graph that you just uploaded:&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">http://tang-song/baitaisi&nbsp;</span>. <br /> <br /> The results in Callimachus are strange. &nbsp;You should see&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">//tang-song/baitaisi</span> in the list, but there are a bunch of other graphs in the triplestore that you never put there. &nbsp;These are graphs that are needed to make Callimachus operate. &nbsp;Now you can understand why using the DROP ALL command has such a devastating effect in Callimachus. &nbsp;The command DROP ALL is faithfully executed by Callimachus and wipes out every graph in the triplestore, including the ones that Callimachus needs to function. &nbsp;The web server continues to operate, but it doesn't actually "know" how to do anything and fails to display any web page of the interface. &nbsp;Why Callimachus allows users to execute this "self-destruct" command is beyond me!<br /> <br /> The graceful way to get rid of your graph in Callimachus is to drop the specific graph rather than all graphs, using this SPARQL Update command:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">DROP GRAPH &lt;http://tang-song/baitaisi&gt;&nbsp;</span><br /> <br /> This will leave intact the other graphs that are necessary for the operation of Callimachus.<br /> <br /> <h2> Specifying the role of a named graph</h2> For the examples in this section, you should load the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">test-baitaisi.ttl</span> and <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">test-baiyugong.ttl</span> files from your hard drive into the triplestore(s) using the SPARQL Update LOAD command as shown in the previous section, naming them with the URIs&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">http://tang-song/baitaisi</span>&nbsp;and&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">http://tang-song/baiyugong</span>&nbsp;respectively. <br /> <br /> The FROM clause is used to specify that triples from particular named graphs should be used as the default graph. &nbsp;There can be more than one named graph specified - the default graph is the merge of triples from all of the specified named graphs [2]. &nbsp;For example, the query<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX geo: &lt;http://www.w3.org/2003/01/geo/wgs84_pos#&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?site</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM &lt;http://tang-song/baitaisi&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM &lt;http://tang-song/baiyugong&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">WHERE {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; ?site a geo:SpatialThing.</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; }</span><br /> <br /> designates that the default graph should be composed of the merge of the two graphs we loaded. &nbsp;The graph pattern in the WHERE clause is applied to all of the triples in both of the graphs (i.e. the default graph). &nbsp;Running the query returns the URIs of both sites represented in the graphs:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baitaisi&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baiyugong&gt;</span><br /> <br /> The FROM NAMED clause is used to say that a named graph is part of the RDF dataset, but that a graph pattern will be applied to that named graph only if it is specified explicitly using the GRAPH keyword. &nbsp;If we wrote the query like this:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX geo: &lt;http://www.w3.org/2003/01/geo/wgs84_pos#&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?site</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM &lt;http://tang-song/baitaisi&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM NAMED &lt;http://tang-song/baiyugong&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">WHERE {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; ?site a geo:SpatialThing.</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; }</span><br /> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span></div> we only get one result:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baitaisi&gt;</span><br /> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span></div> because we didn't specify that the graph pattern should apply to the&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">http://tang-song/baiyugong</span>&nbsp;named graph. &nbsp;In this query:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX schema: &lt;http://schema.org/&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?building</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM &lt;http://tang-song/baitaisi&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM NAMED &lt;http://tang-song/baiyugong&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">WHERE {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; GRAPH &lt;http://tang-song/baiyugong&gt; {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; &nbsp; ?building a schema:LandmarksOrHistoricalBuildings.</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; <span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; }</span><br /> <br /> only buildings described in the&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://tang-song/baiyugong&gt;</span>&nbsp;graph are returned:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baiyugong#Houdian&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baiyugong#Sanxiandian&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baiyugong#Shanmen&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baiyugong#Zhengdian&gt;</span><br /> <br /> More complicated queries can be constructed, like this:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX schema: &lt;http://schema.org/&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX geo: &lt;http://www.w3.org/2003/01/geo/wgs84_pos#&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?site ?building</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM &lt;http://tang-song/baitaisi&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM NAMED &lt;http://tang-song/baiyugong&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">WHERE {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; ?site a geo:SpatialThing.</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; GRAPH &lt;http://tang-song/baiyugong&gt; {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; &nbsp; &nbsp; &nbsp; ?building a schema:LandmarksOrHistoricalBuildings.</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; <span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; }</span><br /> <br /> where sites in the default&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://tang-song/baitaisi&gt;</span>&nbsp;graph are bound, but buildings in the specified&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://tang-song/baiyugong&gt;</span>&nbsp;graph are bound. <br /> <br /> Using <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM</span> and <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM NAMED</span> clauses in a query make it very clear what graphs should be considered for matching with graph patterns in the WHERE clause. <br /> <br /> <h2> What happens if we load a graph without a name?</h2> It is possible to load a graph into a triplestore without giving it a name, as in this SPARQL Update command:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace; font-size: xx-small;">LOAD &lt;file:///c:/Dropbox/tang-song/test-unnamed.ttl&gt;</span><br /> <br /> Assume that this file has been loaded along with the previous two named graphs. &nbsp;What would happen if we ran this query:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX geo: &lt;http://www.w3.org/2003/01/geo/wgs84_pos#&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?site</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">WHERE {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; ?site a geo:SpatialThing.</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; }</span><br /> <br /> When no named graph is specified using a FROM clause, the endpoint applies the query to "the default graph". &nbsp;The problem is that the SPARQL specification is not clear how the default graph should be constructed. &nbsp;Section 13 says "An RDF Dataset comprises one graph, the default graph, which does not have a name, and zero or more named graphs...", which implies that triples loaded into the store without specifying a graph URI will become part of the default graph. &nbsp;This is also implied in Example 1 in Section 13.1, which shows the "Default graph" as being the one without a name. &nbsp;However, it is also clear that "default graph" cannot be synonymous with "unnamed graph", since the FROM clause allows named graphs to be specified as the default graph. &nbsp;So what happens when we run this query? <br /> <br /> On Stardog, the graph pattern binds only a single URI for <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">?site</span>: <br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Anchansi&gt;</span><br /> <br /> This is the site described by the unnamed graph I loaded. &nbsp;However, running the query on Blazegraph and Callimachus produces this result:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baitaisi&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baiyugong&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Anchansi&gt;</span><br /> <br /> which are the URIs for the sites described by the unnamed graph and both of the named graphs! <br /> <br /> This behavior is somewhat disturbing, because it means that the same query, performed on the same graphs loaded into triplestores using the same LOAD commands do NOT produce the same results. &nbsp;The results are implementation-specific. <br /> <br /> <h3> Construction of the dataset in the absence of FROM and FROM NAMED</h3> The <a href="http://graphdb.ontotext.com/documentation/standard/query-behaviour.html#the-default-sparql-dataset">GraphDB documentation</a> sums up the situation like this:<br /> <blockquote class="tr_bq"> The SPARQL specification does not define what happens when no FROM or FROM NAMED clauses are present in a query, i.e., it does not define how a SPARQL processor should behave when no dataset is defined. In this situation, implementations are free to construct the default dataset as necessary.</blockquote> In the absence of FROM and FROM NAMED clauses, GraphDB constructs the dataset's default graph in the same way as Callimachus and Blazegraph: by merging the database's unnamed graph and all named graphs in the database. <br /> <br /> In the absence of FROM and FROM NAMED clauses, all of the applications include all named graphs in the dataset, allowing graph patterns to be applied specifically to them using the GRAPH keyword. &nbsp;So in the case of this query:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX geo: &lt;http://www.w3.org/2003/01/geo/wgs84_pos#&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?site</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">WHERE {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; GRAPH ?g {?site a geo:SpatialThing.}</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; }</span><br /> <br /> we would expect the results to include <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">?site</span> URI bindings from the two named graphs:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baitaisi&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baiyugong&gt;</span><br /> <div> <br /></div> which we do. &nbsp;However, Callimachus and Blazegraph also include:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Anchansi&gt;</span><br /> <br /> in the results, indicating that they consider the empty graph to also bind to <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">?g</span> (Stardog does not).<br /> <br /> <h3> Construction of the dataset when FROM and FROM NAMED clauses are present</h3> If we run this query:<br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX geo: &lt;http://www.w3.org/2003/01/geo/wgs84_pos#&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?site</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM &lt;http://tang-song/baitaisi&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">WHERE {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; ?site a geo:SpatialThing.</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; }</span><br /> <br /> we get the same result on all three platforms - only the site URI&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://lod.vanderbilt.edu/historyart/site/Baitaisi&gt;&nbsp;</span>from the named graph that was specified in the FROM clause. &nbsp;This should be expected, since Section 13.2 of the SPARQL 1.1 specification says<br /> <blockquote class="tr_bq"> A SPARQL query may specify the dataset to be used for matching by using the FROM clause and the FROM NAMED clause to describe the RDF dataset. If a query provides such a dataset description, then it is used in place of <b>any dataset that the query service would use if no dataset description is provided</b> in a query.</blockquote> The bolded text (my emphasis) is suitably vague about what would be included in the dataset in the absence of FROM and FROM NAMED clauses (i.e. the default graph). &nbsp;Section 13.2 also says<br /> <blockquote class="tr_bq"> If there is no FROM clause, but there is one or more FROM NAMED clauses, then the dataset includes an empty graph for the default graph.</blockquote> that is, if only FROM NAMED clauses are included in the query, unnamed graph(s) will NOT be used as the default graph, since the default graph is required to be empty.<br /> <br /> <h3> Querying the entire triplestore using Stardog</h3> The way that Stardog constructs datasets is problematic since there is no straightforward way to include all unnamed and named graphs (i.e. all triples in the store) in the same query. &nbsp;The following query is possible:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX geo: &lt;http://www.w3.org/2003/01/geo/wgs84_pos#&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?site</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">WHERE {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; &nbsp;{?site a geo:SpatialThing.}</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; &nbsp; &nbsp; &nbsp;UNION</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; {GRAPH ?g {?site a geo:SpatialThing.}}</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; }</span><br /> <br /> but complicated, since the desired graph pattern has to be repeated twice in the query. &nbsp;The first graph pattern binds matching triples in the unnamed graph, and the second graph pattern binds matching triples in all of the named graphs.<br /> <br /> <h2> What is the name of an unnamed graph?</h2> Previously, we saw that that the query<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?g WHERE {&nbsp;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>GRAPH ?g {</span><span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">?s ?p ?o</span><span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">}&nbsp;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">}</span><br /> <br /> could be used to ask the names of graphs that were present in the triplestore. &nbsp;Let's find out what happens when we run this query on the three triplestores with the unnamed graph and the two named graphs loaded. &nbsp;Stardog gives this result:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">http://tang-song/baitaisi</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">http://tang-song/baiyugong</span><br /> <br /> which is not surprising since we saw that an early query using GRAPH ?g bound only to the two named graphs. &nbsp;Running the query on Blazegraph produces this somewhat surprising result:<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://tang-song/baitaisi&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://tang-song/baiyugong&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;file:/c:/Dropbox/tang-song/test-unnamed.ttl&gt;</span><br /> <br /> We see the two named graphs, but we also see a URI for the unnamed graph. &nbsp;In the absence of an assigned URI from the LOAD command, Blazegraph has assigned the graph a URI that is almost the file URI (only one slash after <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">file: </span>instead of three). &nbsp;This might explain why all three graphs (including the unnamed graph) bound to the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">?g</span> in an earlier Blazegraph query. &nbsp;However, it does not explain that same behavior in Callimachus, since in Callimachus the current query only lists the two named graphs (besides the many Callimachus utility graphs that make the thing run). <br /> <br /> <h2> Loading graphs using the GUI</h2> Each of the three platforms I've been testing also provide a means to load files into the store using a graphical user interface instead of the SPARQL Update LOAD command. <br /> <h3> <br />Callimachus</h3> To get to the file manager in Callimachus, in the browser URL box enter:<br /> <br /> <a href="http://localhost:8080/?view">http://localhost:8080/?view</a><br /> <br /> You'll see a screen like this:<br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDkMe4JsR3yBYdZXXsQbDZ-ZjrRxaCPQDbTWA4G6PjNPSyleLsfh6VzgjfiI-PRluXD_cwI878tQx6ivJl2b4hK636gSTjgWW5hBh_JJODeiTkwVFLD3mGlRCZVPVZ17NMqDbLxueSDcA/s1600/callimachus-file-manager.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="452" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDkMe4JsR3yBYdZXXsQbDZ-ZjrRxaCPQDbTWA4G6PjNPSyleLsfh6VzgjfiI-PRluXD_cwI878tQx6ivJl2b4hK636gSTjgWW5hBh_JJODeiTkwVFLD3mGlRCZVPVZ17NMqDbLxueSDcA/s640/callimachus-file-manager.png" width="640" /></a></div> You can create subfolders and upload files using the red buttons at the top of the screen. &nbsp;After uploading the unnamed graph file, I ran the query to show all of the named graphs. The one called&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">test-unnamed.ttl</span> showed up on the list. &nbsp;So although loading files using the GUI does not provide an opportunity to specify a name for the graph, Callimachus assigns a name to the graph anyway (the file name). <br /> <h3> <br />Stardog</h3> Before uploading using the GUI, I executed DROP ALL to make sure that all graphs (named and unnamed) were removed from the store. &nbsp;To load a file, select Add from the Data dropdown list at the top of the page. &nbsp;A popup will appear and you will have an opportunity to select the file using a dialog. It looks like this:<br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkujR7adiZqAK79JgToW6hPZELRz-0_oN5_pfeAotOYWNfT5pGdftrOQMx9geiKsHxVZ1pR78Rcf2jCgBv2ObE3gJYT1NdO8vEoe2Qg4SA4Z6mJqDEBqlEqBgpZ1mbq9UpLNuWuvGBODg/s1600/stardog-gui-load.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkujR7adiZqAK79JgToW6hPZELRz-0_oN5_pfeAotOYWNfT5pGdftrOQMx9geiKsHxVZ1pR78Rcf2jCgBv2ObE3gJYT1NdO8vEoe2Qg4SA4Z6mJqDEBqlEqBgpZ1mbq9UpLNuWuvGBODg/s640/stardog-gui-load.png" width="640" /></a></div> <br /> Stardog gives you an opportunity to specify a name for the graph in the box. &nbsp;If you don't put in a name, the URI <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">tag:stardog:api:context:default</span> shows up in the box. &nbsp;I loaded the unnamed graph file and left the graph name box empty, assuming that&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">tag:stardog:api:context:default</span>&nbsp;would be assigned as the name of the graph. &nbsp;However, running the query to list all graphs produced only&nbsp;the URIs for the two explicitly named graphs.<br /> <br /> When I performed the query<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX geo: &lt;http://www.w3.org/2003/01/geo/wgs84_pos#&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?site&nbsp;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM &lt;http://tang-song/baitaisi&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">WHERE {</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; ?site a geo:SpatialThing.</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">}</span><br /> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span></div> <div> I only got one result:</div> <div> <br /></div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">http://lod.vanderbilt.edu/historyart/site/Baitaisi</span></div> <div> <br /></div> <div> But when I included the&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;tag:stardog:api:context:default&gt;</span> graph in a FROM clause:</div> <div> <br /></div> <div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PREFIX geo: &lt;http://www.w3.org/2003/01/geo/wgs84_pos#&gt;</span></div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span></div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">SELECT DISTINCT ?site&nbsp;</span></div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM &lt;http://tang-song/baitaisi&gt;</span></div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">FROM &lt;tag:stardog:api:context:default&gt;</span></div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">WHERE {</span></div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&nbsp; ?site a geo:SpatialThing.</span></div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">}</span></div> </div> <div> <br /></div> <div> I got two results:</div> <div> <br /></div> <div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">http://lod.vanderbilt.edu/historyart/site/Anchansi</span></div> <div> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">http://lod.vanderbilt.edu/historyart/site/Baitaisi</span></div> </div> <div> <br /></div> <div> So in some circumstances, referring to the "name" of the unnamed graph <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;tag:stardog:api:context:default&gt;</span>&nbsp;causes it to behave as a named graph, even though it didn't show up when I ran the query to list the names of all graphs. <br /> <br /></div> <h3> Blazegraph</h3> I also ran DROP ALL on the Update page before loading files using the Blazegraph GUI. &nbsp;At the bottom of the Update page, I changed the dropdown from "SPARQL Update" to "File Path or URL". I then used the Choose File button to initiate a file selection dialog. &nbsp;After selecting the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">test-unnamed.ttl</span> file, the dropdown switched on its own to "RDF Data" with Format: Turtle, and displayed the file in the box, like this:<br /> <br /> <div class="separator" style="clear: both; text-align: center;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_Xs5FQZbsCsMlKXMrP1DuEQMq0oKYYqnhFNitClLyQonc6aAgpHjmdjKiFlOcxkEWGtDFiHdgoEWjeU6lxR6tu9OdVYXmrYIicwCW-h0ma466LXg8IBUcQbEnIlHESBaJftCn86WgSW0/s1600/blazegraph-gui-load.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="474" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_Xs5FQZbsCsMlKXMrP1DuEQMq0oKYYqnhFNitClLyQonc6aAgpHjmdjKiFlOcxkEWGtDFiHdgoEWjeU6lxR6tu9OdVYXmrYIicwCW-h0ma466LXg8IBUcQbEnIlHESBaJftCn86WgSW0/s640/blazegraph-gui-load.png" width="640" /></a></div> <br /> There was no opportunity to specify a URI for the graph. &nbsp;I clicked on the update button, then switched to the query page so that I could run the query to ask the names of the graphs. &nbsp;The graph name <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">bd:nullGraph</span> was given. &nbsp;The namespace shortcuts indicate that <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">bd:</span> is the abbreviation for&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://www.bigdata.com/rdf#&gt;</span>. &nbsp;So using the GUI interface to load an unnamed graph again results in Blazegraph assigning a name to an unnamed graph, this time&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://www.bigdata.com/rdf#nullGraph&gt;</span>&nbsp;instead of a file name-based URI. <br /> <br /> As with Stardog, including the IRI "name" of the unnamed graph in a FROM clause causes it to be added to the default graph.<br /> <br /> <h2> Names of unnamed graphs (review)</h2> Here's what I've discovered so far about how the three SPARQL endpoints/triplestores name graphs when no name is assigned to them by the user upon loading. &nbsp;The examples assume that&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">test-unnamed.ttl</span> is the name of the uploaded file.<br /> <br /> <h4> Callimachus</h4> When loaded using the GUI: <b>the graph name is the file name, e.g.</b> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;test-unnamed.ttl&gt;</span><br /> <br /> When loaded using the SPARQL Update command: <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">LOAD &lt;file:///c:/Dropbox/tang-song/test-unnamed.ttl&gt;</span>: <b>the triples do not appear to be assigned to any named graph</b>.<br /> <br /> <h4> Stardog</h4> When loaded using the GUI, or when loaded using the SPARQL Update command:&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">LOAD &lt;file:///c:/Dropbox/tang-song/test-unnamed.ttl&gt;</span>: &nbsp;<b>the triples are added to the graph named&nbsp;</b><span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;tag:stardog:api:context:default&gt; </span><span style="font-family: inherit;">(although that graph doesn't seem to bind to patterns where there is a variable in the graph position of a graph pattern).</span><br /> <br /> <h4> Blazegraph</h4> When loaded using the GUI:&nbsp;<b>the triples are added to the graph named&nbsp;</b><span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://www.bigdata.com/rdf#nullGraph&gt;</span><br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;"><br /></span> When loaded using the SPARQL Update command:&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">LOAD &lt;file:///c:/Dropbox/tang-song/test-unnamed.ttl&gt;</span>:&nbsp;<b>the graph name is a modification of the file name, e.g.</b>&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;file:/c:/Dropbox/tang-song/test-unnamed.ttl&gt;</span><br /> <br /> For all practical purposes, Blazegraph does not have unnamed graphs - triples always load into some named graph that binds to variables in the graph position of a graph pattern.<br /> <br /> <h2> Deleting unnamed graphs</h2> As noted earlier, deleting a named graph is easy using the<br /> <br /> <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">DROP GRAPH &lt;</span><i>graphURI</i><span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&gt;</span><br /> <br /> command of SPARQL Update. &nbsp;What about deleting the "unnamed" graphs of the flavors I've just described? &nbsp;In all of the cases of named "unnamed" graphs listed above, inserting the URI of the unnamed graph results in the deletion of the graph. &nbsp;That's not surprising, since the aren't really "unnamed" after all. &nbsp;The problematic situation is where triples are loaded into Callimachus using SPARQL Update with no graph name. &nbsp;Those triples can't be deleted using DROP GRAPH because there is no way to refer to their truly unnamed graph. <br /> <br /> <h3> DROP DEFAULT</h3> The <a href="https://www.w3.org/TR/sparql11-update/#drop">SPARQL 1.1 Update specification</a>, Section 3.2.2 give an option for the DROP command called DROP DEFAULT. &nbsp;Given the uncertainty about what is actually considered the "default" graph in the three platforms, I decided to run some tests. <br /> <br /> In Callimachus, DROP DEFAULT doesn't do anything as far as I can tell. &nbsp;That's unfortunate, because it's the only platform that uploads triples into a graph that truly has no name. &nbsp;As far as I can tell, there is no way to use the DROP command to clear out triples that are loaded using the SPARQL Update LOAD command with no graph URI provided. &nbsp;(Well, actually DROP ALL will work if you want to self-destruct the whole system!) <br /> <br /> In Stardog, every loaded graph with an unspecified name goes into the graph&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;tag:stardog:api:context:default&gt;</span>. &nbsp;DROP DEFAULT does delete everything in that graph. <br /> <br /> In Blazegraph, DROP DEFAULT deletes the graph&nbsp;<span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">&lt;http://www.bigdata.com/rdf#nullGraph&gt;</span>, which is where triples uploaded via the GUI go. &nbsp;However, DROP DEFAULT does not delete any of the "file name URI"-graphs that result when graphs are uploaded using the SPARQL Update LOAD command without a provided graph IRI. <br /> <br /> <h2> Summary</h2> Named graphs are likely to be an important part of managing a complex and changing triplestore/SPARQL endpoint, since they are the primary way to run queries over a specific part of the database and the primary way to remove a specified subset of the triples from the store without disturbing the rest of the loaded triples. <br /> <br /> Although it is less complicated to load triples into the store without specifying them as part of a named graph, the handling of "unnamed" graphs by the various platforms is very idiosyncratic. &nbsp;Unnamed graphs introduce complications in querying and management of triples in the store. &nbsp;Specifically:<br /> <br /> <ul> <li>In <b>Callimachus</b>,&nbsp;in some cases&nbsp;there appears to be no simple way to get rid of triples that aren't associated with some flavor of named graph. &nbsp;</li> <li>In <b>Stardog</b>, there is no simple way to use a single graph pattern to query triples in both named and unnamed graphs. &nbsp;</li> <li><b>Blazegraph</b> seems to be the most trouble-free since omitting any FROM or FROM GRAPH clauses allows triples in both named and "unnamed" graphs to be queried using a single graph pattern. &nbsp;I put "unnamed" in quotes because Blazegraph always loads triples into a graph identified with an URI even when one isn't specified by the user. &nbsp;However, knowing what those URIs are is a bit confusing since the URI that is assigned depends on the method used to load the graph.</li> </ul> <br /> My take-home from these experiments is that we are probably best-off continuing with our plan to use Blazegraph as our triplestore, and that we should probably load triples from various sources and projects into named graphs.<br /> <br /> <h2> What I've left out</h2> There are a number of features of the SPARQL endpoints/triplestores that I have not discussed in this post. &nbsp;One is the <b>service description</b> of the endpoint. &nbsp;The SPARQL 1.1 suite of Recommendations includes the <a href="https://www.w3.org/TR/sparql11-service-description/">SPARQL 1.1 Service Description</a> specification. &nbsp;This specification describes how a SPARQL endpoint should provide information about the triplestore to machine clients that discover it. &nbsp; This information includes number of triples, graphs present in the store, namespaces used, etc. &nbsp;A client can request the service description by sending an HTTP GET request to the endpoint without any query string. &nbsp;For example, with Blazegraph, sending a GET to<br /> <br /> <a href="http://localhost:9999/blazegraph/sparql">http://localhost:9999/blazegraph/sparql</a><br /> <br /> returns the service description.<br /> <br /> The various applications also enable <b>partitioning data in the store on a level higher than graphs</b>. &nbsp;For example, Blazegraph supports named "datasets". &nbsp;Querying across different datasets requires doing a <a href="https://www.w3.org/TR/sparql11-federated-query/">federated query</a>, even if the datasets are in the same triplestore. &nbsp;Stardog has a similar feature where its triples are partitioned into "databases" that can be managed independently. <br /> <br /> There are also <b>alternate methods for loading graphs</b> that I haven't mentioned or explored. &nbsp;Because SPARQL Update commands can be made via HTTP, they can be automated by a desktop application that can issue HTTP requests (as opposed to typing the commands in a web form). &nbsp;So with appropriate software, &nbsp;graph maintenance can be automated or carried out at specified intervals. &nbsp;Blazegraph also has a "bulk loader" facility that I have not explored. &nbsp;Clearly there is a lot more details to be learned!<br /> <br /> <br /> [1] GitHub repo at&nbsp;<a href="https://github.com/HeardLibrary/semantic-web">https://github.com/HeardLibrary/semantic-web</a><br /> [2] In the merge, blank nodes are kept distinct within the source graphs. &nbsp;If the same blank node identifier is used in two of the merged graphs, the blank node identifier of one of the graphs will be changed to ensure that it denotes a different resource from the resource identified by the blank node identifier in the other graph. <div style='clear: both;'></div> </div> <div class='post-footer'> <div class='post-footer-line post-footer-line-1'> <span class='post-author vcard'> Posted by <span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://www.blogger.com/profile/01896499749604153763' itemprop='url'/> <a class='g-profile' href='https://www.blogger.com/profile/01896499749604153763' rel='author' title='author profile'> <span itemprop='name'>Steve Baskauf</span> </a> </span> </span> <span class='post-timestamp'> at <meta content='http://baskauf.blogspot.com/2017/02/sparql-weirdness-of-unnamed-graphs.html' itemprop='url'/> <a class='timestamp-link' href='http://baskauf.blogspot.com/2017/02/sparql-weirdness-of-unnamed-graphs.html' rel='bookmark' title='permanent link'><abbr class='published' itemprop='datePublished' title='2017-02-13T20:00:00-08:00'>8:00&#8239;PM</abbr></a> </span> <span class='post-comment-link'> <a class='comment-link' href='http://baskauf.blogspot.com/2017/02/sparql-weirdness-of-unnamed-graphs.html#comment-form' onclick=''> 4 comments: </a> </span> <span class='post-icons'> <span class='item-control blog-admin pid-95103704'> <a href='https://www.blogger.com/post-edit.g?blogID=5299754536670281996&postID=281309205955855307&from=pencil' title='Edit Post'> <img alt='' class='icon-action' height='18' src='https://resources.blogblog.com/img/icon18_edit_allbkg.gif' width='18'/> </a> </span> </span> <div class='post-share-buttons goog-inline-block'> <a class='goog-inline-block share-button sb-email' href='https://www.blogger.com/share-post.g?blogID=5299754536670281996&postID=281309205955855307&target=email' target='_blank' title='Email This'><span class='share-button-link-text'>Email This</span></a><a class='goog-inline-block share-button sb-blog' href='https://www.blogger.com/share-post.g?blogID=5299754536670281996&postID=281309205955855307&target=blog' onclick='window.open(this.href, "_blank", "height=270,width=475"); return false;' target='_blank' title='BlogThis!'><span class='share-button-link-text'>BlogThis!</span></a><a class='goog-inline-block share-button sb-twitter' href='https://www.blogger.com/share-post.g?blogID=5299754536670281996&postID=281309205955855307&target=twitter' target='_blank' title='Share to X'><span class='share-button-link-text'>Share to X</span></a><a class='goog-inline-block share-button sb-facebook' href='https://www.blogger.com/share-post.g?blogID=5299754536670281996&postID=281309205955855307&target=facebook' onclick='window.open(this.href, "_blank", "height=430,width=640"); return false;' target='_blank' title='Share to Facebook'><span class='share-button-link-text'>Share to Facebook</span></a><a class='goog-inline-block share-button sb-pinterest' href='https://www.blogger.com/share-post.g?blogID=5299754536670281996&postID=281309205955855307&target=pinterest' target='_blank' title='Share to Pinterest'><span class='share-button-link-text'>Share to Pinterest</span></a> </div> </div> <div class='post-footer-line post-footer-line-2'> <span class='post-labels'> </span> </div> <div class='post-footer-line post-footer-line-3'> <span class='post-location'> </span> </div> </div> </div> </div> </div></div> </div> <div class='blog-pager' id='blog-pager'> <span id='blog-pager-newer-link'> <a class='blog-pager-newer-link' href='http://baskauf.blogspot.com/search?updated-max=2019-03-10T07:55:00-07:00&amp;max-results=7&amp;reverse-paginate=true' id='Blog1_blog-pager-newer-link' title='Newer Posts'>Newer Posts</a> </span> <span id='blog-pager-older-link'> <a class='blog-pager-older-link' href='http://baskauf.blogspot.com/search?updated-max=2017-02-13T20:00:00-08:00&amp;max-results=7' id='Blog1_blog-pager-older-link' title='Older Posts'>Older Posts</a> </span> <a class='home-link' href='http://baskauf.blogspot.com/'>Home</a> </div> <div class='clear'></div> <div class='blog-feeds'> <div class='feed-links'> Subscribe to: <a class='feed-link' href='http://baskauf.blogspot.com/feeds/posts/default' target='_blank' type='application/atom+xml'>Posts (Atom)</a> </div> </div> </div></div> </div> </div> <div class='column-left-outer'> <div class='column-left-inner'> <aside> </aside> </div> </div> <div class='column-right-outer'> <div class='column-right-inner'> <aside> <div class='sidebar section' id='sidebar-right-1'><div class='widget BlogArchive' data-version='1' id='BlogArchive1'> <h2>Blog Archive</h2> <div class='widget-content'> <div id='ArchiveList'> <div id='BlogArchive1_ArchiveList'> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2025/'> 2025 </a> <span class='post-count' dir='ltr'>(2)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2025/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2025/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2023/'> 2023 </a> <span class='post-count' dir='ltr'>(2)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2023/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2023/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2022/'> 2022 </a> <span class='post-count' dir='ltr'>(4)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2022/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2022/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2022/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2022/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2021/'> 2021 </a> <span class='post-count' dir='ltr'>(4)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2021/03/'> March </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2020/'> 2020 </a> <span class='post-count' dir='ltr'>(5)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2020/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2020/02/'> February </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/'> 2019 </a> <span class='post-count' dir='ltr'>(9)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/06/'> June </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2018/'> 2018 </a> <span class='post-count' dir='ltr'>(1)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2018/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> &#9660;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2017/'> 2017 </a> <span class='post-count' dir='ltr'>(6)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2017/07/'> July </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2017/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2017/03/'> March </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> &#9660;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2017/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> <ul class='posts'> <li><a href='http://baskauf.blogspot.com/2017/02/sparql-weirdness-of-unnamed-graphs.html'>SPARQL: the weirdness of unnamed graphs</a></li> </ul> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/'> 2016 </a> <span class='post-count' dir='ltr'>(15)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/11/'> November </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/10/'> October </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/04/'> April </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/03/'> March </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/02/'> February </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2015/'> 2015 </a> <span class='post-count' dir='ltr'>(6)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2015/09/'> September </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2015/07/'> July </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2014/'> 2014 </a> <span class='post-count' dir='ltr'>(7)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2014/05/'> May </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2014/04/'> April </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> </div> </div> <div class='clear'></div> </div> </div><div class='widget Profile' data-version='1' id='Profile1'> <h2>About Me</h2> <div class='widget-content'> <a href='https://www.blogger.com/profile/01896499749604153763'><img alt='My photo' class='profile-img' height='80' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVm8jF34Q3Q0IttRnG66Z3cjplIPwTfYeVwoznPhxbTRnbtkuN5ekrcV1MNxedjGsgnImAIr_OAT_USbVVyX6pK_xy2GWTQDofBY9K7fiMj9DBOK4_dORjPC0UTaHIvP0/s220/profile-pic-carmen-small.jpg' width='80'/></a> <dl class='profile-datablock'> <dt class='profile-data'> <a class='profile-name-link g-profile' href='https://www.blogger.com/profile/01896499749604153763' rel='author' style='background-image: url(//www.blogger.com/img/logo-16.png);'> Steve Baskauf </a> </dt> </dl> <a class='profile-link' href='https://www.blogger.com/profile/01896499749604153763' rel='author'>View my complete profile</a> <div class='clear'></div> </div> </div></div> </aside> </div> </div> </div> <div style='clear: both'></div> <!-- columns --> </div> <!-- main --> </div> </div> <div class='main-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <footer> <div class='footer-outer'> <div class='footer-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left footer-fauxborder-left'> <div class='fauxborder-right footer-fauxborder-right'></div> <div class='region-inner footer-inner'> <div class='foot no-items section' id='footer-1'></div> <table border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'> <tbody> <tr> <td class='first columns-cell'> <div class='foot no-items section' id='footer-2-1'></div> </td> <td class='columns-cell'> <div class='foot no-items section' id='footer-2-2'></div> </td> </tr> </tbody> </table> <!-- outside of the include in order to lock Attribution widget --> <div class='foot section' id='footer-3' name='Footer'><div class='widget Attribution' data-version='1' id='Attribution1'> <div class='widget-content' style='text-align: center;'> Simple theme. Powered by <a href='https://www.blogger.com' target='_blank'>Blogger</a>. </div> <div class='clear'></div> </div></div> </div> </div> <div class='footer-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </footer> <!-- content --> </div> </div> <div class='content-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <script type='text/javascript'> window.setTimeout(function() { document.body.className = document.body.className.replace('loading', ''); }, 10); </script> <script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/2538535903-widgets.js"></script> <script type='text/javascript'> window['__wavt'] = 'AOuZoY46zEMdSPt6pmEoYf_JH5Djac5zOg:1744369510410';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d5299754536670281996','//baskauf.blogspot.com/2017/02/','5299754536670281996'); _WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '5299754536670281996', 'title': 'Steve Baskauf\x27s blog', 'url': 'http://baskauf.blogspot.com/2017/02/', 'canonicalUrl': 'http://baskauf.blogspot.com/2017/02/', 'homepageUrl': 'http://baskauf.blogspot.com/', 'searchUrl': 'http://baskauf.blogspot.com/search', 'canonicalHomepageUrl': 'http://baskauf.blogspot.com/', 'blogspotFaviconUrl': 'http://baskauf.blogspot.com/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': false, 'httpsEnabled': true, 'enabledCommentProfileImages': true, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': '', 'encoding': 'UTF-8', 'locale': 'en', 'localeUnderscoreDelimited': 'en', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': false, 'isMobileRequest': false, 'mobileClass': '', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Steve Baskauf\x26#39;s blog - Atom\x22 href\x3d\x22http://baskauf.blogspot.com/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22Steve Baskauf\x26#39;s blog - RSS\x22 href\x3d\x22http://baskauf.blogspot.com/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Steve Baskauf\x26#39;s blog - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/5299754536670281996/posts/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/3d05552398782a47', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'X', 'key': 'twitter', 'shareMessage': 'Share to X', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'archive', 'pageName': 'February 2017', 'pageTitle': 'Steve Baskauf\x27s blog: February 2017'}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard!', 'ok': 'Ok', 'postLink': 'Post Link'}}, {'name': 'template', 'data': {'name': 'Simple', 'localizedName': 'Simple', 'isResponsive': false, 'isAlternateRendering': false, 'isCustom': false, 'variant': 'simplysimple', 'variantId': 'simplysimple'}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': false, 'title': 'Steve Baskauf\x27s blog', 'description': '', 'url': 'http://baskauf.blogspot.com/2017/02/', 'type': 'feed', 'isSingleItem': false, 'isMultipleItems': true, 'isError': false, 'isPage': false, 'isPost': false, 'isHomepage': false, 'isArchive': true, 'isLabelSearch': false, 'archive': {'year': 2017, 'month': 2, 'rangeMessage': 'Showing posts from February, 2017'}}}]); _WidgetManager._RegisterWidget('_NavbarView', new _WidgetInfo('Navbar1', 'navbar', document.getElementById('Navbar1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'header', document.getElementById('Header1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false, 'lightboxEnabled': true, 'lightboxModuleUrl': 'https://www.blogger.com/static/v1/jsbin/3337823330-lbx.js', 'lightboxCssUrl': 'https://www.blogger.com/static/v1/v-css/3681588378-lightbox_bundle.css'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogArchiveView', new _WidgetInfo('BlogArchive1', 'sidebar-right-1', document.getElementById('BlogArchive1'), {'languageDirection': 'ltr', 'loadingMessage': 'Loading\x26hellip;'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_ProfileView', new _WidgetInfo('Profile1', 'sidebar-right-1', document.getElementById('Profile1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_AttributionView', new _WidgetInfo('Attribution1', 'footer-3', document.getElementById('Attribution1'), {}, 'displayModeFull')); </script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10