Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gizmo: make methods lower case #822

Merged
merged 14 commits into from
Sep 22, 2019
460 changes: 257 additions & 203 deletions docs/GizmoAPI.md

Large diffs are not rendered by default.

100 changes: 58 additions & 42 deletions docs/Quickstart-As-Application.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ This guide will take you through starting a persistent graph based on the provid
Grab the latest [release binary](http://github.com/cayleygraph/cayley/releases) and extract it wherever you like.
If you have Docker installed you can check [guide](Container.md) for running Cayley in container.

If you prefer to build from source, see [Contributing.md](Contributing.md) which has instructions.
If you prefer to build from source, see [Contributing.md](Contributing.md) which has instructions.

### Quick preview

### Quick preview ###
If you downloaded the correct binary the fastest way to have a peak into Cayley is to load one of the example data file in the ./data directory, and query them by the web interface.

```bash
Expand Down Expand Up @@ -110,7 +111,6 @@ cayley> graph.Vertex("<dani>").All()
cayley> graph.Vertex("<dani>").Out("<follows>").All()
```


### Serve Your Graph

Just as before:
Expand All @@ -127,37 +127,39 @@ listening on :64210, web interface at http://localhost:64210

If you visit that address (often, [http://localhost:64210](http://localhost:64210)) you'll see the full web interface and also have a graph ready to serve queries via the [HTTP API](HTTP.md)

#### Access from other machines ####
#### Access from other machines

When you want to reach the API or UI from another machine in the network you need to specify the host argument:

```bash
./cayley http --config=cayley.cfg.overview --host=0.0.0.0:64210
```
This makes it listen on all interfaces. You can also give it the specific the IP address you want Cayley to bind to.

**Warning**: for security reasons you might not want to do this on a public accessible machine.
This makes it listen on all interfaces. You can also give it the specific the IP address you want Cayley to bind to.

**Warning**: for security reasons you might not want to do this on a public accessible machine.

## UI Overview

### Sidebar

Along the side are the various actions or views you can take. From the top, these are:

* Run Query (run the query)
* Gizmo (a dropdown, to pick your query language, MQL is the other)
* [GizmoAPI.md](GizmoAPI.md): This is the one of the two query languages used either via the REPL or HTTP interface.
* [MQL.md](MQL.md): The *other* query language the interfaces support.
- Run Query (run the query)
- Gizmo (a dropdown, to pick your query language, MQL is the other)
- [GizmoAPI.md](GizmoAPI.md): This is the one of the two query languages used either via the REPL or HTTP interface.
- [MQL.md](MQL.md): The _other_ query language the interfaces support.

----
---

* Query (a request/response editor for the query language)
* Query Shape (a visualization of the shape of the final query. Does not execute the query.)
* Visualize (runs a query and, if tagged correctly, gives a sigmajs view of the results)
* Write (an interface to write or remove individual quads or quad files)
- Query (a request/response editor for the query language)
- Query Shape (a visualization of the shape of the final query. Does not execute the query.)
- Visualize (runs a query and, if tagged correctly, gives a sigmajs view of the results)
- Write (an interface to write or remove individual quads or quad files)

----
---

* Documentation (this documentation)
- Documentation (this documentation)

### Visualize

Expand All @@ -167,15 +169,15 @@ For example:

```javascript
[
{
"source": "node1",
"target": "node2"
},
{
"source": "node1",
"target": "node3"
},
]
{
source: "node1",
target: "node2"
},
{
source: "node1",
target: "node3"
}
];
```

Other keys are ignored. The upshot is that if you use the "Tag" functionality to add "source" and "target" tags, you can extract and quickly view subgraphs.
Expand All @@ -184,12 +186,12 @@ Other keys are ignored. The upshot is that if you use the "Tag" functionality to
// 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.

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**

Expand All @@ -201,27 +203,32 @@ The simplest query is merely to return a single vertex. Using the 30kmoviedata.n

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

// Start with only one vertex, the literal name "Humphrey Bogart", and retrieve all of them.
graph.Vertex("Humphrey Bogart").All()
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()
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()
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()
g.V("Casablanca")
.in("<name>")
.all();

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


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

Start somewhere in the graph | Follow a path | Run the query with "All" or "GetLimit"
Expand All @@ -232,16 +239,25 @@ And these pipelines continue...

```javascript
// 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()
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()
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.
2 changes: 1 addition & 1 deletion docs/api/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ paths:
examples:
gizmo:
summary: "Gizmo: first 10 nodes"
value: "g.V().GetLimit(10)"
value: "g.V().getLimit(10)"
graphql:
summary: "GraphQL: first 10 nodes"
value: "{\n nodes(first: 10){\n id\n }\n}"
Expand Down
60 changes: 30 additions & 30 deletions graph/graphtest/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ var queries = []struct {
{
message: "name predicate",
query: `
g.V("Humphrey Bogart").In("<name>").All()
g.V("Humphrey Bogart").in("<name>").all()
`,
expect: []interface{}{
map[string]string{"id": "</en/humphrey_bogart>"},
Expand All @@ -105,11 +105,11 @@ var queries = []struct {
{
message: "two large sets with no intersection",
query: `
function getId(x) { return g.V(x).In("<name>") }
var actor_to_film = g.M().In("</film/performance/actor>").In("</film/film/starring>")
function getId(x) { return g.V(x).in("<name>") }
var actor_to_film = g.M().in("</film/performance/actor>").in("</film/film/starring>")

getId("Oliver Hardy").Follow(actor_to_film).Out("<name>").Intersect(
getId("Mel Blanc").Follow(actor_to_film).Out("<name>")).All()
getId("Oliver Hardy").follow(actor_to_film).out("<name>").intersect(
getId("Mel Blanc").follow(actor_to_film).out("<name>")).all()
`,
expect: nil,
},
Expand All @@ -119,19 +119,19 @@ var queries = []struct {
message: "three huge sets with small intersection",
long: true,
query: `
function getId(x) { return g.V(x).In("<name>") }
var actor_to_film = g.M().In("</film/performance/actor>").In("</film/film/starring>")
function getId(x) { return g.V(x).in("<name>") }
var actor_to_film = g.M().in("</film/performance/actor>").in("</film/film/starring>")

var a = getId("Oliver Hardy").Follow(actor_to_film).FollowR(actor_to_film)
var b = getId("Mel Blanc").Follow(actor_to_film).FollowR(actor_to_film)
var c = getId("Billy Gilbert").Follow(actor_to_film).FollowR(actor_to_film)
var a = getId("Oliver Hardy").follow(actor_to_film).followR(actor_to_film)
var b = getId("Mel Blanc").follow(actor_to_film).followR(actor_to_film)
var c = getId("Billy Gilbert").follow(actor_to_film).followR(actor_to_film)

seen = {}

a.Intersect(b).Intersect(c).ForEach(function (d) {
a.intersect(b).intersect(c).forEach(function (d) {
if (!(d.id in seen)) {
seen[d.id] = true;
g.Emit(d)
g.emit(d)
}
})
`,
Expand All @@ -148,7 +148,7 @@ var queries = []struct {
message: "the helpless checker",
long: true,
query: `
g.V().As("person").In("<name>").In().In().Out("<name>").Is("Casablanca").All()
g.V().as("person").in("<name>").in().in().out("<name>").is("Casablanca").all()
`,
tag: "person",
expect: []interface{}{
Expand All @@ -175,7 +175,7 @@ var queries = []struct {
message: "the helpless checker, negated (films without Ingrid Bergman)",
long: true,
query: `
g.V().As("person").In("<name>").In().In().Out("<name>").Except(g.V("Ingrid Bergman").In("<name>").In().In().Out("<name>")).Is("Casablanca").All()
g.V().as("person").in("<name>").in().in().out("<name>").except(g.V("Ingrid Bergman").in("<name>").in().in().out("<name>")).is("Casablanca").all()
`,
tag: "person",
expect: nil,
Expand All @@ -184,7 +184,7 @@ var queries = []struct {
message: "the helpless checker, negated (without actors Ingrid Bergman)",
long: true,
query: `
g.V().As("person").In("<name>").Except(g.V("Ingrid Bergman").In("<name>")).In().In().Out("<name>").Is("Casablanca").All()
g.V().as("person").in("<name>").except(g.V("Ingrid Bergman").in("<name>")).in().in().out("<name>").is("Casablanca").all()
`,
tag: "person",
expect: []interface{}{
Expand All @@ -209,7 +209,7 @@ var queries = []struct {
//A: "Sandra Bullock"
{
message: "Net and Speed",
query: common + `m1_actors.Intersect(m2_actors).Out("<name>").All()
query: common + `m1_actors.intersect(m2_actors).out("<name>").all()
`,
expect: []interface{}{
map[string]string{"id": SandraB, "movie1": "The Net", "movie2": nSpeed},
Expand All @@ -220,7 +220,7 @@ var queries = []struct {
//A: No
{
message: "Keanu in The Net",
query: common + `actor2.Intersect(m1_actors).Out("<name>").All()
query: common + `actor2.intersect(m1_actors).out("<name>").all()
`,
expect: nil,
},
Expand All @@ -229,7 +229,7 @@ var queries = []struct {
//A: Yes
{
message: "Keanu in Speed",
query: common + `actor2.Intersect(m2_actors).Out("<name>").All()
query: common + `actor2.intersect(m2_actors).out("<name>").all()
`,
expect: []interface{}{
map[string]string{"id": KeanuR, "movie2": nSpeed},
Expand All @@ -242,7 +242,7 @@ var queries = []struct {
{
message: "Keanu with other in The Net",
long: true,
query: common + `actor2.Follow(coStars1).Intersect(m1_actors).Out("<name>").All()
query: common + `actor2.follow(coStars1).intersect(m1_actors).out("<name>").all()
`,
expect: []interface{}{
map[string]string{"id": SandraB, "movie1": "The Net", "costar1_movie": nSpeed},
Expand All @@ -256,7 +256,7 @@ var queries = []struct {
{
message: "Keanu and Bullock with other",
long: true,
query: common + `actor1.Save("<name>","costar1_actor").Follow(coStars1).Intersect(actor2.Save("<name>","costar2_actor").Follow(coStars2)).Out("<name>").All()
query: common + `actor1.save("<name>","costar1_actor").follow(coStars1).intersect(actor2.save("<name>","costar2_actor").follow(coStars2)).out("<name>").all()
`,
expect: []interface{}{
costarTag(SandraB, SandraB, "The Proposal", KeanuR, nSpeed),
Expand Down Expand Up @@ -430,7 +430,7 @@ var queries = []struct {
{
message: "Save a number of predicates around a set of nodes",
query: `
g.V("_:9037", "_:49278", "_:44112", "_:44709", "_:43382").Save("</film/performance/character>", "char").Save("</film/performance/actor>", "act").SaveR("</film/film/starring>", "film").All()
g.V("_:9037", "_:49278", "_:44112", "_:44709", "_:43382").save("</film/performance/character>", "char").save("</film/performance/actor>", "act").saveR("</film/film/starring>", "film").all()
`,
expect: []interface{}{
map[string]string{"act": "</en/humphrey_bogart>", "char": "Rick Blaine", "film": "</en/casablanca_1942>", "id": "_:9037"},
Expand All @@ -443,21 +443,21 @@ var queries = []struct {
}

const common = `
var movie1 = g.V().Has("<name>", "The Net")
var movie2 = g.V().Has("<name>", "Speed")
var actor1 = g.V().Has("<name>", "Sandra Bullock")
var actor2 = g.V().Has("<name>", "Keanu Reeves")
var movie1 = g.V().has("<name>", "The Net")
var movie2 = g.V().has("<name>", "Speed")
var actor1 = g.V().has("<name>", "Sandra Bullock")
var actor2 = g.V().has("<name>", "Keanu Reeves")

// (film) -> starring -> (actor)
var filmToActor = g.Morphism().Out("</film/film/starring>").Out("</film/performance/actor>")
var filmToActor = g.Morphism().out("</film/film/starring>").out("</film/performance/actor>")

// (actor) -> starring -> [film -> starring -> (actor)]
var coStars1 = g.Morphism().In("</film/performance/actor>").In("</film/film/starring>").Save("<name>","costar1_movie").Follow(filmToActor)
var coStars2 = g.Morphism().In("</film/performance/actor>").In("</film/film/starring>").Save("<name>","costar2_movie").Follow(filmToActor)
var coStars1 = g.Morphism().in("</film/performance/actor>").in("</film/film/starring>").save("<name>","costar1_movie").follow(filmToActor)
var coStars2 = g.Morphism().in("</film/performance/actor>").in("</film/film/starring>").save("<name>","costar2_movie").follow(filmToActor)

// Stars for the movies "The Net" and "Speed"
var m1_actors = movie1.Save("<name>","movie1").Follow(filmToActor)
var m2_actors = movie2.Save("<name>","movie2").Follow(filmToActor)
var m1_actors = movie1.save("<name>","movie1").follow(filmToActor)
var m2_actors = movie2.save("<name>","movie2").follow(filmToActor)
`

func prepare(t testing.TB, gen testutil.DatabaseFunc) (graph.QuadStore, func()) {
Expand Down
Loading