A Variety of Questions


I’ve found Cayley to be quite intriguing, since most of my database-related experience has been with relational databases (MySQL in particular). I’ve been attempting to dig into the code, the docs, and search here on discourse to try to find the appropriate usage and entry points regarding the golang api.

While what I’ve found in the way of documentation has been sparse and somewhat unclear (which is completely understandable), I’ve managed to gain a little understanding of how to store and retrieve data on a basic level using a few different methods. I really like what I’m seeing, but I get the distinct impression there is so much more functionality available than what I’ve discovered.

Is there some hidden treasure of documentation that I can assimilate as I go, or should I just ask a bunch of questions on here as I think of them and hope I get a response?

Since I’m already here, I might as well start on the latter:

  • What is a morphism, and when would I want to use it?

  • What should I expect Path.Follow() to do, and how should I be using it?

  • I’d like to programmatically and intuitively provide data to the end user, giving them the ability to drill down to the data they want–a query wizard, if you will. Should I be using simple paths for this, or is there a better avenue? (This would be a great addition to the standalone application interface–I would enjoy writing the pull request for it, if I could find the time)

  • How does one go about using an iterator properly?

  • For what should the graph/shape sub-package be used?

  • How should I query using the schema lib functionality, especially when what I want to retrieve might be N-relations (which might vary in predicate) away?

  • Does the standalone application have any authentication/security features?

  • Is there any plan to improve the documentation, whether in godoc form, or something entirely different (so I can ask more informed questions)?

    I’m sure I can think up some more questions, and I think I forgot much of what I wanted to ask while writing the ones I managed to articulate. I’m sorry if any of them are too ambiguous, I appreciate any input I can get. Thanks for your time!


Morphism is basically a path that is not attached to any particular quadstore or a particular starting point in the graph. Morphisms are meant to be used as a query part that can be applied to other queries to follow a path specified in the Morphism.

A good example will be a FollowRecursive function that will apply a single morphism multiple times to get to all nodes that can be traversed recursively.

Follow can be used to apply a specific Morphism. This means that you can write a specific set of constraints for a node, create a Path for it, and then apply it to other Paths using Follow. The same can be done for traversal - you can create a Path with a specific traversal and apply it to other queries later.

Hmm, this is an interesting question. Paths are just a set of helpers to build a query, but they are not that good for building something more complex. You can try using Shapes for this - it will give you a full control of what the query actually does. Some functionality exists in Shapes, but not in Paths.

We also plan to make Shapes serializable at some point, so client applications will be able to build a query and send it to the server, or even store queries in the DB.

And PRs are always welcome, so feel free to ask more specific questions regarding the code, if you have any :slight_smile:

There are is an only one rule: make sure you close it. The usage of iterator should be pretty straightforward and be similar to database/sql.Rows. Please check ./examples/hello_bolt for a code sample.

This is the most interesting part of the query system - it describes how exactly the query looks like. You can try the following: build a Path, call Shape() and print it with fmt.Printf("%#v", s). It will give you a dump of the query tree in Go syntax that you can try to modify.

This package also describes different query optimizations that are not specific to a backend. If you find that a specific query is too slow, you can check what shape it generates and in most cases you would find that the shape is not optimal, meaning that query optimizer is not that smart yet :sweat_smile:

The schema package was build with a interoperability in mind. You can write a query using either Paths, Shapes or raw Iterators and pass it as a starting point to a schema lib and it will load an object for you. An oposite is true: you can write a query with schema, build an iterator from it, and use it to continue the query using Paths or Iterators.

I hope this answers your question.

Not yet. You can always place it behind the proxy, or file a PR with an auth implementation :wink:

Sure, it would be awesome. But currently we don’t have enough resources for it, unfortunately :frowning:

Always ready to help, so feel free to send more questions, if you like :slight_smile:


You say that the only rule for using an iterator is to close it. Does this still apply to iterators that are attached to a memory quadstore?