{"id":17531,"date":"2017-06-26T12:15:48","date_gmt":"2017-06-26T09:15:48","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=17531"},"modified":"2017-06-23T11:52:12","modified_gmt":"2017-06-23T08:52:12","slug":"graph-database-goodness-levelgraph","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/","title":{"rendered":"Graph Database Goodness with LevelGraph"},"content":{"rendered":"<p>Graph databases are one in a plethora of NoSQL databases now found in the wild. They\u2019re unique among their sibling database types by having a unique internal data structure. Graph databases make the relationships within the data a first-class citizen on the same level as the data itself.<\/p>\n<p>Consequently, they are most popular in social networking, big data, and science and research communities. These domains have datasets that are as much about the relationships they encode as they are about the data. When everything\u2019s interconnected \u2014 say, like on the web \u2014 then the real power of this model starts to become apparent.<\/p>\n<p>So, rather than focusing on pairing data values to meaning (column heading, key name, etc), graph databases express things using:<\/p>\n<ul>\n<li>Nodes \u2014 the subject of the relationship<\/li>\n<li>Edges \u2014 the relationships between Nodes and Properties<\/li>\n<li>Properties \u2014 the information related to the Node<\/li>\n<\/ul>\n<p>Here\u2019s what a graph database might look like:<\/p>\n<blockquote><p>BigBlueHat writesFor Codeship<\/p><\/blockquote>\n<p>Reads like a sentence, right? In fact, in \u201ctriplestores\u201d (a common graph database implementation type), these terms map to the following, more grammatically friendly names:<\/p>\n<ul>\n<li>Subject \u2014 the thing being talked about (node)<\/li>\n<li>Predicate \u2014 what\u2019s being said about the subject relative to the object (edge)<\/li>\n<li>Object \u2014 the thing related to the subject (property)<\/li>\n<\/ul>\n<p>Simpler, right? Here are some more:<\/p>\n<blockquote><p>BigBlueHat contributesTo LevelGraph<\/p>\n<p>BrightBall writesFor Codeship<\/p>\n<p>BigBlueHat postsCodeAt https:\/\/github.com\/bigbluehat<\/p><\/blockquote>\n<p>These statements use the same \u201cwritesFor\u201d predicate, so finding out \u201cwho writes for Codeship\u201d would be trivial. But what if we wanted to ask \u201cWhere do authors at Codeship post code?\u201d If you squint, you\u2019ll see two sets of potential algebraic-looking sentences in there:<\/p>\n<blockquote><p>X writesFor Codeship<\/p>\n<p>X postsCodeAt Y<\/p><\/blockquote>\n<p>This ability to stack and relate other relationships into cascading related queries is one of the core powers of graph databases.<\/p>\n<p>Mind blown yet? Let\u2019s back up.<\/p>\n<h2>How to Build a Hexastore<\/h2>\n<p><a href=\"http:\/levelgraph.io\">LevelGraph<\/a> is an implementation of a \u201chexastore\u201d which is built upon <a href=\"https:\/\/github.com\/Level\/levelup\">LevelUp<\/a> and <a href=\"https:\/\/github.com\/google\/leveldb\">LevelDB<\/a>. Hexastores combine the consistent nature of triplestores with the boring but beneficial power of materialized indexes.<\/p>\n<p>Given the triples we used above, you could imagine a key\/value-based master index with all the triples (subject, predicate, object) stored as the key with <code>null<\/code> or <code>1<\/code> or anything stored as the value. Doing that would give one the power to find all the relationships of a single subject.<\/p>\n<p>For instance, you can imagine the statements above stored in Redis (or whatever) as these keys \u2014 each with a value of <code>1<\/code>:<\/p>\n<blockquote><p>BigBlueHat|writesFor|Codeship<\/p>\n<p>BigBlueHat|contributesTo|LevelGraph<\/p>\n<p>BrightBall|writesFor|Codeship<\/p>\n<p>BigBlueHat|postsCodeAt|https:\/\/github.com\/bigbluehat<\/p><\/blockquote>\n<p>Given the above, we could answer simple queries like \u201cwho does BigBlueHat writeFor?\u201d or \u201cwhat do we know about Brightball?\u201d But we could not ask the more complex query mentioned above or answer something more common like \u201cwho writesFor Codeship?\u201d<\/p>\n<p>Hexastores use this same basic \u201ckey-heavy\u201d storage style, but they store the same data six different ways. Seriously. Let\u2019s have a look.<\/p>\n<p>We\u2019ll store S P O as our triple (for simplicity). A hexastore would store these six keys:<\/p>\n<blockquote><p>S|P|O<\/p>\n<p>S|O|P<\/p>\n<p>P|O|S<\/p>\n<p>P|S|O<\/p>\n<p>O|S|P<\/p>\n<p>O|P|S<\/p><\/blockquote>\n<p>Seem crazy? Maybe. But it\u2019s also crazy efficient for lookups.<\/p>\n<p>Let\u2019s look at that query from earlier:<\/p>\n<blockquote><p>X writesFor CodeShip<\/p>\n<p>X postsCodeAt Y<\/p><\/blockquote>\n<p>Given that query, we\u2019d use the keys that have a P|O|S structure first (to answer for \u201cX\u201d) and, once we\u2019ve solved for X, we\u2019d check the S|P|O keys where X = S.<\/p>\n<p>Remember, these are range-based, boring-old, materialized lookups. They\u2019re not doing table scans. They\u2019re jumping straight to that point in the index and returning what they find. Afterword, there\u2019s some combination \u2014 if needed.<\/p>\n<p>The above query, then, we\u2019d check this range first:<\/p>\n<blockquote><p>writesFor|CodeShip|*<\/p><\/blockquote>\n<p>which would return these keys from our little dataset:<\/p>\n<blockquote><p>writesFor|CodeShip|BigBlueHat<\/p>\n<p>writesFor|CodeShip|BrightBall<\/p><\/blockquote>\n<p>Then, using those results, we\u2019d hit the index again, looking for this range:<\/p>\n<blockquote><p>BigBlueHat|postsCodeAt|*<\/p><\/blockquote>\n<p>Which would result in this key:<\/p>\n<blockquote><p>BigBlueHat|postsCodeAt|https:\/\/github.com\/BigBlueHat<\/p><\/blockquote>\n<p>We now have the answers to our \u201ccomplex\u201d little question. Pretty rad, right?<\/p>\n<p>Onward.<\/p>\n<h2>Meet LevelGraph<\/h2>\n<p>LevelGraph is (as mentioned) an implementation of a hexastore. It uses LevelUp and LevelDB as a foundational key\/value store. In the browser, it uses <a href=\"https:\/\/github.com\/maxogden\/level.js\">level.js<\/a> to store the same sort of hexastore key-based master index (as seen above) into an IndexedDB database.<\/p>\n<p>LevelGraph can be installed via <a href=\"http:\/\/browserify.org\/\">browserify<\/a>. <a href=\"https:\/\/github.com\/mcollina\/levelgraph#install\">Installation instructions<\/a> can be found in the <a href=\"https:\/\/github.com\/mcollina\/levelgraph\"><code>levelgraph<\/code> GitHub repo<\/a>.<\/p>\n<p>Putting data into LevelGraph looks like:<\/p>\n<pre class=\"brush:php\">db.put({\r\n subject: \"BigBlueHat\",\r\n predicate: \"writesFor\",\r\n object: \"Codeship\"\r\n}, function(err) {\r\n if (err) throw err;\r\n});<\/pre>\n<p>In this case, if there\u2019s an error, it will get thrown. Otherwise, it\u2019s safe to assume the triple went in verbatim.<\/p>\n<p>Once the data has been added to LevelGraph, the underlying LevelDB (or IndexedDB if you\u2019re in a browser) will show keys looking rather similar to the ones above.<\/p>\n<p>Getting data out of LevelGraph takes one of three forms:<\/p>\n<ul>\n<li><code>db.get()<\/code> for a all triples containing any combination of a subject, predicate, or object<\/li>\n<li><code>db.search()<\/code> for doing queries like the one we did before + filtering + materialization<\/li>\n<li><code>db.nav.*<\/code> chained queries using methods similar to the Gremlin query system from Apache Tinkerpop and friends<\/li>\n<\/ul>\n<p>Let\u2019s take a look at each of those in turn.<\/p>\n<p>First, a basic <code>db.get()<\/code> could be used to answer the \u201cwho writesFor Codeship?\u201d question above:<\/p>\n<pre class=\"brush:php\">db.get({\r\n predicate: \"writesFor\",\r\n object: \"Codeship\"\r\n}, function(err, rv) {\r\n if (err) throw err;\r\n console.log('rv', rv);\r\n});<\/pre>\n<p>The output is a an array of triples (subject, predicate, object) that contain the \u201cwritesFor\u201d predicate and the \u201cCodeship\u201d object values. We can use the callback to extract just the subjects from those objects giving an array of answers to our question:<\/p>\n<pre class=\"brush:php\">db.get({\r\n predicate: \"writesFor\",\r\n object: \"Codeship\"\r\n}, function(err, rv) {\r\n if (err) throw err;\r\n writers = rv.map(function(triple) {\r\n return triple.subject;\r\n });\r\n console.log('writers', writers);\r\n \/\/ writers = [\"BigBlueHat\", \"Brightball\"]\r\n});<\/pre>\n<p>Next, let\u2019s take a look at that more complex query using the <code>db.search()<\/code> API.<\/p>\n<pre class=\"brush:php\">\/\/ X writesFor Codeship\r\n\/\/ X postsCodeAt Y\r\ndb.search([\r\n {\r\n subject: db.v('x'),\r\n predicate: \"writesFor\",\r\n object: \"Codeship\"\r\n },\r\n {\r\n subject: db.v('x'),\r\n predicate: \"postsCodeAt\",\r\n object: db.v('y')\r\n }\r\n],\r\n{}, \/\/ we'll talk about this shortly\r\nfunction(err, rv) {\r\n if (err) throw err;\r\n console.log('rv', rv);\r\n});<\/pre>\n<p>The output is an array of results mapped to their <code>db.v()<\/code> value holders.<\/p>\n<pre class=\"brush:php\">\/\/ output of the above `db.search`\r\nrv = [{x: \"BigBlueHat\", y: \"https:\/\/github.com\/bigbluehat\"}]<\/pre>\n<p>It\u2019s also possible to include a <code>filter<\/code> function alongside any triple used in the search queries. This can be helpful for further limiting the output as the queries cascade into each other. For instance, if we only wanted code posted on GitHub, we could make the second search query object read:<\/p>\n<pre class=\"brush:php\">{\r\n  subject: db.v('x'),\r\n  predicate: \"postsCodeAt\",\r\n  object: db.v('y'),\r\n  filter: function(triple) {\r\n    return triple.object.search(\"github.com\") &gt; -1;\r\n  }\r\n}<\/pre>\n<p>Once the results are in, we can also provide a final <code>filter<\/code> in that second parameter we say earlier (currently set to <code>{}<\/code>). However, those filter functions take a slightly different using a callback function to confirm or reject the result (aka the solution to the query):<\/p>\n<pre class=\"brush:php\">function filter(solution, callback) {\r\n \/\/ we're only looking for things starting with `B`\r\n if ('x' in solution &amp;&amp; solution.x.search(\/\\^B\/) &gt; -1) {\r\n   \/\/ confirm\/keep the solution\/result\r\n   callback(null, solution);\r\n } else {\r\n   \/\/ reject\/skip\r\n   callback(null);\r\n }\r\n}<\/pre>\n<p>Additionally, if we wanted to reshape the output back into triples, we can use the <code>materialized<\/code> object. This is most useful when creating new triples within the graph based on results found from a search query.<\/p>\n<p>For example:<\/p>\n<pre class=\"brush:php\">{\r\n  materialized: {\r\n    subject: \"Codeship\",\r\n    predicate: \"authorCodeRepository\",\r\n    object: db.v('y')\r\n  }\r\n}<\/pre>\n<p>The result in this case being a new triple of:<\/p>\n<blockquote><p>Codeship authorCodeRepository https:\/\/github.com\/bigbluehat<\/p><\/blockquote>\n<p>This can be super handy when you need to change the shape of the graph or make new statements into other graphs. Additionally, you can use the materialized output to do additional <code>db.get()<\/code> and <code>db.search()<\/code> requests using the materialized output as the query options in the next request or perhaps even removing any remaining statements from the graph that used a different predicate.<\/p>\n<p>Removing triples looks rather like putting them, only the method is <code>db.del()<\/code>:<\/p>\n<pre class=\"brush:php\">db.del(\r\n  {subject: \"BigBlueHat\", predicate: \"postsCodeAt\",\r\n   object: \"https:\/\/github.com\/bigbluehat\"},\r\n  function(err) { if (err) throw err; });<\/pre>\n<p>LevelGraph looks up the six variations of the triple-based keys in the hexastore and deletes them. If it can\u2019t find the key(s), it throws an error.<\/p>\n<p>Now. Editing is going to feel a bit odd\u2026<\/p>\n<p>Because these are key names and not values, we can\u2019t just alter them in place. We have to remove them and then put the new ones in.<\/p>\n<p>Let\u2019s change the <code>https:\/\/github.com\/bigbluehat<\/code> URL to <code>https:\/\/github.com\/BigBlueHat\/<\/code> (which is technically more accurate). We\u2019ll start with the <code>db.del()<\/code> operation above, and then <code>db.put()<\/code> the replacement:<\/p>\n<pre class=\"brush:php\">db.del(\r\n  {subject: \"BigBlueHat\", predicate: \"postsCodeAt\",\r\n   object:\"https:\/\/github.com\/bigbluehat\"},\r\n  function(err) {\r\n    if (err) throw err;\r\n    db.put({subject: \"BigBlueHat\", predicate: \"postsCodeAt\",\r\n            object: \"https:\/\/github.com\/BigBlueHat\/\"},\r\n      function(err) { if (err) throw err; });\r\n  });<\/pre>\n<p>That should do it. In fact, you could reverse those, so you\u2019d be sure that the new stuff made it in before you removed the old one. Let\u2019s do that in the next example.<\/p>\n<p>The code above works when we know a single triple that has the string we need to update in it. If we need to update all occurrences of the string in the graph, then we\u2019ll need to search for them all and then re-put them. Like so:<\/p>\n<pre class=\"brush:php\">db.search([\r\n  {subject: db.v('s'), predicate: db.v('p'),\r\n   object:\"https:\/\/github.com\/bigbluehat\"}],\r\n  {},\r\n  function(err, rv) {\r\n    rv.forEach(function(r) {\r\n      \/\/ putting the new stuff in first, to be sure it makes it in\r\n      db.put({subject: r.s, predicate: r.p,\r\n              object: \"https:\/\/github.com\/BigBlueHat\/\"},\r\n        function(err) {\r\n          if (err) throw err;\r\n          \/\/ new stuff is in, so let's remove the old\r\n          db.del({subject: r.s, predicate: r.p,\r\n            object: \"http:\/\/github.com\/bigbluehat\"},\r\n            function(err) { if (err) throw err; }\r\n          );\r\n        }\r\n      );\r\n    });\r\n  });<\/pre>\n<p>While that may seem tedious, it has the advantage of being progressive improvement \u2014 good stuff in, then bad stuff out \u2014 or the other way around if you\u2019d like. It\u2019s up to you.<\/p>\n<p>One thing worth noting is that we\u2019ve not had to name any columns or figure out primary or secondary keys. We didn\u2019t even have to determine what we were going to index before we stored something. Since the data has this consistent, triple-based shape throughout the process, those things are implicitly handled.<\/p>\n<p>Let\u2019s move on to Linked Data.<\/p>\n<h2>Linked Data Land<\/h2>\n<p>LevelGraph is one of many hexastore implementations, but it\u2019s use in Node.js and the browsers, meaning that it\u2019s an ideal candidate for building apps for working with Linked Data.<\/p>\n<p>Linked Data uses this same graph-based thinking plus the webby nature of graphs (or is it the graphy nature of the web\u2026) and brings that to data \u2014 not just documents.<\/p>\n<p>Our examples above were fine for what they are, but they assumed (rashly) a closed world environment in which \u201cwritesFor\u201d is seen as sufficient within the closed world of our little graph. However, what happens when the two of us exchange data and you used something like \u201cauthorsFor\u201d? What happens if English isn\u2019t your native language?<\/p>\n<p>That\u2019s where Linked Data comes in.<\/p>\n<p>Let\u2019s go back to that very first triple:<\/p>\n<blockquote><p>BigBlueHat writesFor Codeship<\/p><\/blockquote>\n<p>In this triple, we\u2019re using plain strings made of English words to be the identifiers of the things themselves. Trouble is, that don\u2019t scale so good.<\/p>\n<p>Here\u2019s what that same triple would look like using the Schema.org Linked Data vocabulary developed by Google, Microsoft, Yahoo, Yandex, and friends and developed in a W3C Community Group:<\/p>\n<blockquote><p>https:\/\/blog.codeship.com\/json-ld-building-meaningful-data-apis\/ http:\/\/schema.org\/author http:\/\/bigbluehat.com\/#me<\/p>\n<p>https:\/\/blog.codeship.com\/json-ld-building-meaningful-data-apis\/ http:\/\/schema.org\/publisher https:\/\/codeship.com\/#<\/p><\/blockquote>\n<p>We\u2019ve now made two global-friendly statements using five total identifiers. Interestingly, we\u2019ve now introduced an identifier (and in this case it\u2019s also a locator) of something published <em>and<\/em> authored \u2014 which is information we\u2019d lacked before.<\/p>\n<p>However, there\u2019s now no direct relationship between the \u201cBigBlueHat\u201d identifier and the \u201cCodeship\u201d (blog) identifier. That said, we now specify one of the things that \u201cBigBlueHat\u201d actually wrote for \u201cCodeship\u201d and a URL of where it\u2019s published, so those are wins to be sure.<\/p>\n<p>But how do we find out \u201cwho writes for the Codeship blog\u201d now?<\/p>\n<pre class=\"brush:php\">db.search([\r\n  {\r\n    subject: db.v('article'),\r\n    predicate: \"http:\/\/schema.org\/author\",\r\n    object: db.v('author')\r\n  },\r\n  {\r\n    subject: db.v('article'),\r\n    predicate: \"http:\/\/schema.org\/publisher\",\r\n    object: db.v('publisher')\r\n  }],\r\n  {},\r\n  function(err, rv) {\r\n    if (err) throw err;\r\n    console.log('rv', rv);\r\n  }\r\n);<\/pre>\n<p>The output should look like this:<\/p>\n<pre class=\"brush:php\">rv = [\r\n  {\r\n    author: \"http:\/\/bigbluehat.com\/#me\",\r\n    article: \"https:\/\/blog.codeship.com\/json-ld-building-meaningful-data-apis\/\",\r\n    publisher: \"https:\/\/codeship.com\/#\"\r\n  }\r\n];<\/pre>\n<p>If we were to update Brightball\u2019s triple statements to use the Schema.org vocabulary, there\u2019d be more results. Additionally, we could use a <code>filter<\/code> function at the end to clear out the article names if we were only interested in authors, for instance. However, in this case, we have even richer data returned than we did earlier, not to mention more accurately defined data!<\/p>\n<h2>Conclusion<\/h2>\n<p>This only scratches the surface of both LevelGraph and Linked Data. The graph model can take some time to get your head around, but it\u2019s one that\u2019s been increasingly delightful to work with as I learn the tooling, understand graph querying, and build more tools around it.<\/p>\n<p>If you\u2019re new to all this and want to play with LevelGraph without the installation setup, give the <a href=\"https:\/\/github.com\/google\/leveldb\">LevelGraph Playground<\/a> a look.<\/p>\n<p>You can add colloquial (\u201cclosed world\u201d) graphs if you\u2019d like, but it also supports common Linked Data formats such as JSON-LD, Turtle, and N3. JSON-LD is increasingly common and if you\u2019ve landed at the Schema.org site while reading this article, you might enjoy testing out their JSON-LD examples on the playground.<\/p>\n<p>The graphs that will be stored don\u2019t always connect, so they\u2019re not necessarily great for testing queries against. However, those examples should give you a quick way to build up a larger graph.<\/p>\n<p>Lastly, you can also then output any filtered results into JSON-LD or Turtle and send them off to other people who can add them to their graph. If you use the same vocabulary, then you\u2019ll both benefit from the shared meaningful data that you can query across your own personal knowledge store.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"https:\/\/blog.codeship.com\/graph-database-goodness-with-levelgraph\/\">Graph Database Goodness with LevelGraph<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a> Benjamin Young at the <a href=\"http:\/\/blog.codeship.com\/\">Codeship Blog<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Graph databases are one in a plethora of NoSQL databases now found in the wild. They\u2019re unique among their sibling database types by having a unique internal data structure. Graph databases make the relationships within the data a first-class citizen on the same level as the data itself. Consequently, they are most popular in social &hellip;<\/p>\n","protected":false},"author":147,"featured_media":927,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[472],"class_list":["post-17531","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-development","tag-levelgraph"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Graph Database Goodness with LevelGraph - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Graph databases are one in a plethora of NoSQL databases now found in the wild. They\u2019re unique among their sibling database types by having a unique\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Graph Database Goodness with LevelGraph - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Graph databases are one in a plethora of NoSQL databases now found in the wild. They\u2019re unique among their sibling database types by having a unique\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-06-26T09:15:48+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Benjamin Young\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Benjamin Young\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/\"},\"author\":{\"name\":\"Benjamin Young\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/caa7920cfde365335817761979a72407\"},\"headline\":\"Graph Database Goodness with LevelGraph\",\"datePublished\":\"2017-06-26T09:15:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/\"},\"wordCount\":2071,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"keywords\":[\"LevelGraph\"],\"articleSection\":[\"Web Dev\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/\",\"name\":\"Graph Database Goodness with LevelGraph - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"datePublished\":\"2017-06-26T09:15:48+00:00\",\"description\":\"Graph databases are one in a plethora of NoSQL databases now found in the wild. They\u2019re unique among their sibling database types by having a unique\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Dev\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/web-development\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Graph Database Goodness with LevelGraph\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/caa7920cfde365335817761979a72407\",\"name\":\"Benjamin Young\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/793ddd7d9809b369c04dbc92ea77a896112cc0a0e9a25417a43c17f4afb06f39?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/793ddd7d9809b369c04dbc92ea77a896112cc0a0e9a25417a43c17f4afb06f39?s=96&d=mm&r=g\",\"caption\":\"Benjamin Young\"},\"description\":\"Benjamin Young is a User Experience Engineer and Information Architect. He also organizes @RESTFest &amp; @OpenUpstate.\",\"url\":\"https:\/\/www.webcodegeeks.com\/author\/benjamin-young\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Graph Database Goodness with LevelGraph - Web Code Geeks - 2026","description":"Graph databases are one in a plethora of NoSQL databases now found in the wild. They\u2019re unique among their sibling database types by having a unique","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/","og_locale":"en_US","og_type":"article","og_title":"Graph Database Goodness with LevelGraph - Web Code Geeks - 2026","og_description":"Graph databases are one in a plethora of NoSQL databases now found in the wild. They\u2019re unique among their sibling database types by having a unique","og_url":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2017-06-26T09:15:48+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","type":"image\/jpeg"}],"author":"Benjamin Young","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Benjamin Young","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/"},"author":{"name":"Benjamin Young","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/caa7920cfde365335817761979a72407"},"headline":"Graph Database Goodness with LevelGraph","datePublished":"2017-06-26T09:15:48+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/"},"wordCount":2071,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","keywords":["LevelGraph"],"articleSection":["Web Dev"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/","url":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/","name":"Graph Database Goodness with LevelGraph - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","datePublished":"2017-06-26T09:15:48+00:00","description":"Graph databases are one in a plethora of NoSQL databases now found in the wild. They\u2019re unique among their sibling database types by having a unique","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/web-development\/graph-database-goodness-levelgraph\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Web Dev","item":"https:\/\/www.webcodegeeks.com\/category\/web-development\/"},{"@type":"ListItem","position":3,"name":"Graph Database Goodness with LevelGraph"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/caa7920cfde365335817761979a72407","name":"Benjamin Young","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/793ddd7d9809b369c04dbc92ea77a896112cc0a0e9a25417a43c17f4afb06f39?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/793ddd7d9809b369c04dbc92ea77a896112cc0a0e9a25417a43c17f4afb06f39?s=96&d=mm&r=g","caption":"Benjamin Young"},"description":"Benjamin Young is a User Experience Engineer and Information Architect. He also organizes @RESTFest &amp; @OpenUpstate.","url":"https:\/\/www.webcodegeeks.com\/author\/benjamin-young\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/17531","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/147"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=17531"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/17531\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/927"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=17531"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=17531"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=17531"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}