Skip to content

shamansir/cayley-rust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status

In progress, but may be used for a simple things

NB: Built over nightly Rust, but not guaranteed to be up-to-date with the very latest version, since it is was made for fun. While I use it, though, it will appear rather fresh for some time, I suppose.

About

Cayley is a new graph-driven Database engine from Google, read about it in their Github or in different articles.

API Docs

API Docs (rustdoc).

Code example

To get a first impression on how it looks in action, see test with queries to 30K-Movie database and path compilation test sources.

Usage

Add these lines to your Cargo.toml:

[dependencies.cayley]
git = "https://github.com/shamansir/cayley-rust"
doc = false

And then, in any file you want to use Cayley, add:

extern crate cayley;

Just don't forget to start Cayley DB itself before every session:

$ ./cayley http --dbpath=<your-database>

To connect to a graph at localhost:64210, use code like this:

use cayley::{Graph, V1};

let graph = match Graph::new("localhost", 64210, V1) {
    Err(error) => panic!(error),
    Ok(graph) => graph
};

A simple query pattern looks like this:

use cayley::{GraphNode, GraphNodes};

use cayley::path::{Vertex, Query}; // NB! `Query` is required.
use cayley::selector::AnyNode;

//               The query itself
match graph.find(Vertex::start(AnyNode).All()) {

    Err(error) => panic!(error.to_string()),
    Ok(GraphNodes(nodes)) => {
        assert!(nodes.len() > 0);
        match nodes.iter().next() {
            Some(&GraphNode(ref first_node)) => {
                // node is a HashMap<String, String>
                println!("{:s}", first_node["id".to_string()]);
            },
            None => panic!("first node was not found")
        }
    }

};

NB: Query trait is required to be imported to give you access to .All() method of a Vertex instance. If you feel you don't like it, feel free to support my post in Rust language discussions.

Look for more complex requests just below.

Syntax examples

Due to Rust strict typing, it's hard to transfer free-minded JS-inspired query syntax from Cayley as-is. Though I decided to leave upper-case style for Query/Path methods, since i.e. no method can be named in() in Rust, because in is a keyword.

Here are some parallels:

1.

Gremlin:

graph.Vertex().All()

cayley-rust:

graph.find(Vertex::start(AnyNode).All())
2.

Gremlin:

graph.Vertex("C").Out("follows").GetLimit(5)

cayley-rust:

graph.find(Vertex::start(Node("C")).OutP(Predicate("follows")).GetLimit(5))
3.

Gremlin:

var friendOfFriend = Morphism().Out("follows").Out("follows")

cayley-rust:

let friendOfFriend = Morphism::start("friendOfFriend")
                              .OutP(Predicate("follows"))
                              .OutP(Predicate("follows"));
4.

Gremlin:

g.V("C").Follow(friendOfFriend).Has("status","cool_person")

cayley-rust:

...
use cayley::path::Vertex as V;

let g = Graph::new(...);
let mut friendOfFriend = Morphism::start("friendOfFriend");
        friendOfFriend.OutP...;
...
g.find(V::start(Node("C"))
         .Follow(&friendOfFriend)
         .Has(Predicate("status"), Node("cool_person")));

Possible drawbacks

I have no actual sense if it is correct to use String/to_string() in some cases, but I really tried to avoid that as much as possible, and I plan to try further, if it's not. Or, please, you PRs are welcome.

TODO

Features

Things from Gremlin API still not implemented:

  • query.ToArray() — not supported with HTTP requests
  • query.ToValue() — not supported with HTTP requests
  • query.TagArray() — not supported with HTTP requests
  • query.TagValue() — not supported with HTTP requests
  • query.ForEach(callback), query.ForEach(limit, callback) a.k.a query.Map
  • graph.Emit(data)

API improvements

  • API change: Store GraphNodes as a map with immutable strings (see above, p.2 in Possible Drawbacks section);
  • Preparing Vertex for re-use requires to start a query using .From() selector, and this case should be checked by API for sure;
  • May be, better Error API;

Thanks

Thanks to all Rust IRC members for help.

About

✋ Rust wrapper/driver for Cayley

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages