DEV Community

Cover image for Gram: a data graph format
Andreas Kollegger for Neo4j, Inc.

Posted on • Edited on

Gram: a data graph format

Gram is a textual format for data. We have CSV for tables, JSON for documents, and gram for data graphs.

Use gram when [a,b,c] becomes (a)-->(b)<--(c).

Why another data format?

Anything worth talking about is worth inventing a language for.

-- probably not L. Wittgenstein

Graphs are a powerful and increasingly popular way to think about and work with data. ISO has established a project to formalize an
international standard Graph Query Language. ISO GQL will become the "language of graphs".

But graph technology includes databases, analytics libraries, visualization software, and a host of other tools.

How do we use these things together? We need a common format to connect tools when performing the usual operations:

  • import/export data file
  • send/receive network transmissions
  • copy & paste across applications

We all expect these actions to just work. It's frustrating when any of them are not possible. Tools with limited interoperability feel locked-in and isolated. That's not the graph way.

Gram can make it possible for data graphs to be used in normal everyday work.


Another standard

Data graphs as information architecture

While there are existing graph formats, gram is designed to complement the Property Graph Model defined by ISO GQL.

Gram is interested in information architectures. Data graphs are the means, not the goal. Rather than talking about graphs, gram speaks in graph to talk about other things.

Some motivating examples include:

  • Association class: How do we describe the relationship between two things? Not just that they are connected, but how they are connected.
  • Decorator pattern: Can multiple applications share data while reserving space for their own use?
  • U.S. Route 66: How can we represent path membership and also information about the path itself?
  • Bill of materials with finished goods: How do we describe both the plan to build stuff and the stuff that has been built?

Gram attempts to address these scenarios while being friendly to read and write by adopting a path-based representation. Paths all the way down, or all the way up with path composition.

Friendly to read and write

Gram is intuitively simple, inspired by Cypher1 path expressions.

Information starts with a familiar looking data record of nested properties:

({
    name:"Andreas Kollegger", 
    address: {
        city:"Malmö", country:"Sweden"
    }
})
Enter fullscreen mode Exit fullscreen mode

The extra set of parenthesis wrapping the record provides space for an identifier and a set of labels:

(a:Person:Author { name:"Andreas Kollegger", address: { city:"Malmö", country:"Sweden" }})
Enter fullscreen mode Exit fullscreen mode

Data records can be composed into information structures using relationships:

(a)-[:Wrote]->(b:Blog {title:"Gram: a data graph format"})
Enter fullscreen mode Exit fullscreen mode

We can complete this scene with another related record:

(b:Blog)<-[:Read]-(c:Person)
Enter fullscreen mode Exit fullscreen mode

Putting it all together we could write:

(a:Person)-[:Wrote]->(b:Blog)<-[:Read]-(c:Person)
(a:Author { name:"Andreas Kollegger", address: { city:"Malmö", country:"Sweden" }})
(b {title:"Gram: a data graph format"})
(c {when:date`2021-01-21`})
Enter fullscreen mode Exit fullscreen mode

Nice. The first path is readable as a sentence that "a Person Wrote a Blog that was Read by another Person." Notice in this rewrite we accumulated information -- all the a's are the same record.

Like writing prose, you don't have to say everything at once. Paths appear in an ordered stream that merges forward into a final result. In fact, because any path or sequence of paths forms a valid result you can time-travel or page through a graph.

Use gram for data graphs

Gram is:

  • friendly to read and write
  • composable, sliceable, pageable and streamable
  • vendor-neutral
  • a work-in-progress :)

There is a reference implementation called gram-js which is used along with d3.js in a collection of ObservableHQ notebooks. Next up is integration with other Javascript libraries and conversion to/from other formats.

Check it out and let me know what you think!


Footnotes:

[1] Cypher Language inspired both ISO GQL and gram with the use of "ASCII art" to draw graph elements. cypher is a graph database query language.

[2] Gram of Graphs - an Observable HQ notebook collection which illustrates how to use gram and provides handy utilities for visualizing graphs.

[3] gram-js - the gram reference implementation, written in TypeScript

Top comments (0)