Skip to content
An open-source graph database
Go JavaScript Ragel in Ruby Host CSS HTML Python Other
Find file
Latest commit 15ab599 Mar 23, 2016 @barakmich barakmich Merge pull request #386 from barakmich/optional_path
Add SaveOptional() to save predicates if they exist, and add the
Failed to load latest commit information.
Godeps Merge pull request #277 from barakmich/upgrade_db Oct 5, 2015
appengine internal: move {config,db,http} into internal Aug 11, 2015
cmd graph: make quadstore init functions idempotent Nov 25, 2015
data graph/path: Add LabelContext to the path query language. Oct 30, 2015
docs Add LabelContext to the docs Oct 30, 2015
exporter formatted using gofmt Aug 15, 2015
graph Add SaveOptional() tests. Mar 23, 2016
integration Combine AND(Fixed, SQL) into a single IN clause, reducing roundtrips.… Nov 12, 2015
internal Merge pull request #292 from ds--/master Oct 5, 2015
quad first working-ish Postgres backend Aug 12, 2015
query Fix interface conversion Feb 28, 2016
static Widened visualisation box to 100% Jun 10, 2015
svg Initial Commit Jun 20, 2014
templates Rename triple entities were relevant Aug 27, 2014
writer Ensure that quads in a transaction are applied in the desired order. Nov 17, 2015
.gitignore Update README.md Jul 31, 2015
.goxc.json changed to new testdata file that is now used throughout the document… Apr 22, 2015
.travis.yml Roll the Go version forward on Travis builds (new stable) Aug 19, 2015
AUTHORS Added myself to the A+C Jun 14, 2015
CONTRIBUTING.md Initial Commit Jun 20, 2014
CONTRIBUTORS Add myself to contributors Oct 1, 2015
Dockerfile dockerfile: fix go install command Dec 6, 2015
LICENSE Initial Commit Jun 20, 2014
README.md README: add container section Nov 25, 2015
TODO.md updated TODO.md Jun 17, 2015
cayley.cfg.example Initial Commit Jun 20, 2014
imports.go add Triple function Nov 25, 2015

README.md

Cayley

Cayley is an open-source graph inspired by the graph database behind Freebase and Google's Knowledge Graph.

Its goal is to be a part of the developer's toolbox where Linked Data and graph-shaped data (semantic webs, social networks, etc) in general are concerned.

Build Status Container Repository on Quay

Features

  • Written in Go
  • Easy to get running (3 or 4 commands, below)
  • RESTful API
    • or a REPL if you prefer
  • Built-in query editor and visualizer
  • Multiple query languages:
    • JavaScript, with a Gremlin-inspired* graph object.
    • (simplified) MQL, for Freebase fans
  • Plays well with multiple backend stores:
  • Modular design; easy to extend with new languages and backends
  • Good test coverage
  • Speed, where possible.

Rough performance testing shows that, on consumer hardware and an average disk, 134m quads in LevelDB is no problem and a multi-hop intersection query -- films starring X and Y -- takes ~150ms.

* Note that while it's not exactly Gremlin, it certainly takes inspiration from that API. For this flavor, see the documentation.

Getting Started

Grab the latest release binary and extract it wherever you like.

If you prefer to build from source, see the documentation on the wiki at How to start hacking on Cayley or type

mkdir -p ~/cayley && cd ~/cayley
export GOPATH=`pwd`
export PATH=$PATH:~/cayley/bin
mkdir -p bin pkg src/github.com/google
cd src/github.com/google
git clone https://github.com/google/cayley
cd cayley
go get github.com/tools/godep
godep restore
go build ./cmd/cayley

Then cd to the directory and give it a quick test with:

./cayley repl --dbpath=data/testdata.nq

To run the web frontend, replace the "repl" command with "http"

./cayley http --dbpath=data/testdata.nq

You should see a cayley> REPL prompt. Go ahead and give it a try:

// Simple math
cayley> 2 + 2

// JavaScript syntax
cayley> x = 2 * 8
cayley> x

// See all the entities in this small follow graph.
cayley> graph.Vertex().All()

// See only dani.
cayley> graph.Vertex("dani").All()

// See who dani follows.
cayley> graph.Vertex("dani").Out("follows").All()

Running the visualizer on the web frontend

To run the visualizer: click on visualize and enter:

// Visualize who dani follows.
g.V("dani").Tag("source").Out("follows").Tag("target").All()

The visualizer expects to tag nodes as either "source" or "target." Your source is represented as a blue node. While your target is represented as an orange node. The idea being that our node relationship goes from blue to orange (source to target).

Sample Data

For somewhat more interesting data, a sample of 30k movies from Freebase comes in the checkout.

./cayley repl --dbpath=data/30kmoviedata.nq.gz

To run the web frontend, replace the "repl" command with "http"

./cayley http --dbpath=data/30kmoviedata.nq.gz

And visit port 64210 on your machine, commonly http://localhost:64210

Running queries

The default environment is based on Gremlin and is simply a JavaScript environment. If you can write jQuery, you can query a graph.

You'll notice we have a special object, graph or g, which is how you can interact with the graph.

The simplest query is merely to return a single vertex. Using the 30kmoviedata.nq dataset from above, let's walk through some simple queries:

// Query all vertices in the graph, limit to the first 5 vertices found.
graph.Vertex().GetLimit(5)

// Start with only one vertex, the literal name "Humphrey Bogart", and retrieve all of them.
graph.Vertex("Humphrey Bogart").All()

// `g` and `V` are synonyms for `graph` and `Vertex` respectively, as they are quite common.
g.V("Humphrey Bogart").All()

// "Humphrey Bogart" is a name, but not an entity. Let's find the entities with this name in our dataset.
// Follow links that are pointing In to our "Humphrey Bogart" node with the predicate "name".
g.V("Humphrey Bogart").In("name").All()

// Notice that "name" is a generic predicate in our dataset.
// Starting with a movie gives a similar effect.
g.V("Casablanca").In("name").All()

// Relatedly, we can ask the reverse; all ids with the name "Casablanca"
g.V().Has("name", "Casablanca").All()

You may start to notice a pattern here: with Gremlin, the query lines tend to:

Start somewhere in the graph | Follow a path | Run the query with "All" or "GetLimit"

g.V("Casablanca") | .In("name") | .All()

And these pipelines continue...

// Let's get the list of actors in the film
g.V().Has("name","Casablanca")
  .Out("/film/film/starring").Out("/film/performance/actor")
  .Out("name").All()

// But this is starting to get long. Let's use a morphism -- a pre-defined path stored in a variable -- as our linkage

var filmToActor = g.Morphism().Out("/film/film/starring").Out("/film/performance/actor")

g.V().Has("name", "Casablanca").Follow(filmToActor).Out("name").All()

There's more in the JavaScript API Documentation, but that should give you a feel for how to walk around the graph.

Running in a container

A container exposing the HTTP API of cayley is available. To run the container one must first setup a data directory that contains the configuration file and optionally contains persistent files (i.e. a boltdb database file).

mkdir data
cp my_config.cfg data/cayley.cfg
docker run -v $PWD/data:/data -p 64321:64321 -d quay.io/barakmich/cayley

Disclaimer

Not a Google project, but created and maintained by a Googler, with permission from and assignment to Google, under the Apache License, version 2.0.

Contact

Something went wrong with that request. Please try again.