Skip to content

Quickstart Guide

Matt edited this page Nov 29, 2021 · 17 revisions

In this guide, we'll go from zero to compiling a complex Aspen file.

Assumptions

This guide assumes three things:

  • You know how to use the command line effectively.
  • You have Ruby installed.
  • You have Docker or Neo4j installed.

If one or more of these things isn't true, ask for help in Discussions.

Setup

First, install Aspen. This is the only step where you'll have to refer to another page.

Once Aspen is installed, run aspen new quickstart. This will create a bunch of files in a folder called quickstart/. You could name replace "quickstart" with anything you want—whatever word comes after aspen new is the project name.

Move into the folder by running cd quickstart.

Open this folder using your code editor. Here's a quick rundown of everything you're seeing.

  • bin holds the executable files. Inside bin is a convert script, which, if necessary, helps you convert non-Aspen files like spreadsheets into Aspen
  • build holds the latest "build" of your project. Every time you run aspen build, this project will hold the transpiled files generated from your Aspen code (like Cypher, GEXF, JSON, etc.)
  • config holds project configuration, like database credentials in db.yml, and credentials to include external resources like Airtable or Google Sheets.
  • db (you may or may not have this folder) contains the bind mounts that support a Dockerized instance of Neo4j. Someday we'll replace these with volumes.
  • src contains all of your Aspen files—including narratives, discourses, and grammars—and non-Aspen data files, like spreadsheets. We'll get into what each of those are later.

Writing our data

Narrative

Create a new file in src called main.aspen. In it, include this content:

(Liz) [knows] (Jack).
(Jack) [mentors] (Liz).
(Tracy) [is friends with] (Kenneth).
Lutz, Toofer, and Frank are writers.

In Aspen, this is called a narrative. Simply put, narratives describe the information we want to turn into graph data.

Inspired by Cypher, the "vanilla" Aspen syntax has entities (people, things, ideas) wrapped in () parentheses, while connecting words are wrapped in [] square brackets.

Notice that the last line doesn't have parentheses or brackets. This line is special, and we'll come back to this in the section called Grammars.

Discourse

How does Aspen know that Liz, Jack, Tracy, and everyone else are people, and that the string "Liz" is a name and not a barcode ID, car model, or other piece of data?

It doesn't—until you tell it!

A discourse in Aspen describes the narrative and helps Aspen understand how to interpret the data.

In src/discourses (the discourses folder inside the src folder), create a new file called main.aspen. This will be our main discourse file.

In this file, add the following content:

default:
  label: Person
  attribute: name

reciprocal: knows, is friends with

This is saying that, by default, we should interpret nodes (entities) as people, with a type Person. We should also assume that strings like "Liz" and "Jack" are to be assigned to an attribute called name.

We can assume that since Tracy is friends with Kenneth, Kenneth is also friends with Tracy—there's a reciprocity here, and it's not one-sided. By listing knows and is friends with after reciprocal, we're telling Aspen to interpret these types of relationships as mutual.

Grammar

The last line in the narrative doesn't have the "vanilla" Aspen syntax of (Subject) [relationship] (Object).

Lutz, Toofer, and Frank are writers.

To capture relationships like these that are more than just a simple connecting relationship, we have to write what Aspen calls a "Custom Grammar".

A custom grammar is a small pattern-matching program that explains how to turn complex sentences into data.

Create a file in src/grammars called main.aspen. Add this block of code:

grammar:
  match:
    - (Person a), (Person b), and (Person c) are writers.
  template:
    {{{a}}}-[:HAS_ROLE]->(:Role { type: "Writer" })
    {{{b}}}-[:HAS_ROLE]->(:Role { type: "Writer" })
    {{{c}}}-[:HAS_ROLE]->(:Role { type: "Writer" })

This tells Aspen to interpret "Frank", "Toofer", and "Lutz" as names of Person nodes, and to run the Cypher in the template: section.

If we wanted to be able to write a line like "A, B, and C are video editors" by replacing "writers" with a matcher, we can—but we'll leave that to the Grammar documentation page to go in depth.

Building

Now that we've written our narrative, our discourse, and our grammar, it's time to turn them into Cypher and put them in a Neo4j database.

The Aspen command-line tool includes a build command that transpiles Aspen to other languages, much in the way Markdown transpiles to HTML. (This is different from compiling, which turns code into machine code. We still use "compile" to describe transpilation, though, since it's a more pleasant word to say.)

From inside the quickstart folder, run bundle exec ../bin/aspen build. (We hope for a more elegant command someday.)

Now, look inside the build folder. You should see a few files, one ending in .cql—this is the Cypher file. Open it up and you'll find the Cypher that came from our Aspen file. (Note how much longer the Cypher is, even for a small project like this! That's one major benefit of Aspen.)

Pushing to a Database

Now that we have our Cypher file, it's time to push that to a database.

Run docker-compose up from the quickstart folder. If, after a minute or two, a Neo4j database is booted up, our test has passed! We just wanted to make sure it booted. Press Cmd+C to quit.

Then, run docker-compose up -d so that the database runs in the background.

Run bundle exec ../bin/aspen push. This will replace all the data in the sandbox database we have running in Docker with the data from the freshly-transpiled Cypher.

Keep in mind never to use this tool with a production database—it deletes absolutely everything.

Run docker-compose down when you're ready to shut down the sandbox database.

Keep Learning

Nice work! High five! 💥 🙏🏼 💥

You just learned the basics of Aspen.

To keep learning, go back to the Wiki homepage.

If you have a question, need help, etc., pop over to the Discussions tab and ask away!

Documentation

Quickstart Guide

Clone this wiki locally