1
0
Fork 0

Update demo graphs (UI + documentation) (#5535)

This commit is contained in:
maxkernbach 2018-06-27 14:16:44 +02:00 committed by Jan
parent e99952206d
commit 6586504441
18 changed files with 168 additions and 29 deletions

View File

@ -2,9 +2,9 @@ Multiple Path Search
====================
The shortest path algorithm can only determine one shortest path.
For example, if this is the full graph:
For example, if this is the full graph (based on the [mps_graph](../../Manual/Graphs/index.html#the-mps-graph)):
![Example Graph](sp_graph.png)
![Example Graph](mps_graph.png)
then a shortest path query from **A** to **C** may return the path `A -> B -> C` or `A -> D -> C`, but it's undefined which one (not taking edge weights into account here).
@ -16,7 +16,7 @@ You can use the efficient shortest path algorithm however, to determine the shor
@DATASET{mps_graph}
RETURN LENGTH(
FOR v IN OUTBOUND
SHORTEST_PATH "verts/A" TO "verts/C" edges
SHORTEST_PATH "mps_verts/A" TO "mps_verts/C" mps_edges
RETURN v
)
@END_EXAMPLE_AQL
@ -31,8 +31,8 @@ The following query returns all parts with length 2, start vertex **A** and targ
@startDocuBlockInline GRAPHTRAV_multiplePathSearch2
@EXAMPLE_AQL{GRAPHTRAV_multiplePathSearch2}
@DATASET{mps_graph}
FOR v, e, p IN 2..2 OUTBOUND "verts/A" edges
FILTER v._id == "verts/C"
FOR v, e, p IN 2..2 OUTBOUND "mps_verts/A" mps_edges
FILTER v._id == "mps_verts/C"
RETURN CONCAT_SEPARATOR(" -> ", p.vertices[*]._key)
@END_EXAMPLE_AQL
@endDocuBlock GRAPHTRAV_multiplePathSearch2

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -134,6 +134,8 @@ with a length greater than *max* will never be computed.
In the current state, `AND` combined filters can be optimized, but `OR`
combined filters cannot.
The following examples are based on the [traversal graph](../../Manual/Graphs/index.html#the-traversal-graph).
### Filtering on paths
Filtering on paths allows for the most powerful filtering and may have the

View File

@ -201,6 +201,7 @@ This is how we create it, inspect its *vertices* and *edges*, and drop it again:
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock graph_create_knows_sample
**Note:** with the default "Search Depth" of 2 of the graph viewer you may not see all edges of this graph.
### The Social Graph
@ -263,8 +264,12 @@ Circles have unique numeric labels. Edges have two boolean attributes (*theFalse
@END_EXAMPLE_ARANGOSH_RUN
@endDocuBlock graph_create_traversal_sample
**Note:** with the default "Search Depth" of 2 of the graph viewer you may not see all nodes of this graph.
### The World Graph
![world graph](world_graph.png)
The world country graph structures its nodes like that: world → continent → country → capital. In some cases edge directions aren't forward (therefore it will be displayed disjunct in the graph viewer). It has two ways of creating it. One using the named graph utilities (*worldCountry*), one without (*worldCountryUnManaged*).
It is used to demonstrate raw traversal operations.
@ -280,6 +285,26 @@ It is used to demonstrate raw traversal operations.
@END_EXAMPLE_ARANGOSH_RUN
@endDocuBlock graph_create_world_sample
### The Mps Graph
This graph was created to demonstrate a use case of the shortest path algorithm. Even though the algorithm can only determine one shortest path, it is possible to return multiple shortest paths with two separate queries. Therefore the graph is named after the [**m**ultiple **p**ath **s**earch](../../AQL/Examples/MultiplePaths.html) use case.
![mps graph](mps_graph.png)
The example graph consists of *vertices* in the `mps_verts` collection and *edges* in the `mps_edges` collection. It is a simple traversal graph with start node *A* and end node *C*.
This is how we create it, inspect its *vertices* and *edges*, and drop it again:
@startDocuBlockInline graph_create_mps_sample
@EXAMPLE_ARANGOSH_OUTPUT{graph_create_mps_sample}
var examples = require("@arangodb/graph-examples/example-graph.js");
var g = examples.loadGraph("mps_graph");
db.mps_verts.toArray();
db.mps_edges.toArray();
examples.dropGraph("mps_graph");
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock graph_create_mps_sample
### Higher volume graph examples
All of the above examples are rather small so they are easier to comprehend and can demonstrate the way the functionality works. There are however several datasets freely available on the web that are a lot bigger. [We collected some of them with import scripts](https://github.com/arangodb/example-datasets) so you may play around with them. Another huge graph is the [Pokec social network](https://snap.stanford.edu/data/soc-pokec.html) from Slovakia that we [used for performance testing on several databases](https://www.arangodb.com/2015/06/multi-model-benchmark/); You will find importing scripts etc. in this blogpost.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -1,7 +1,7 @@
@Q:
RETURN LENGTH(
FOR v IN OUTBOUND
SHORTEST_PATH <span class="hljs-string">"verts/A"</span> TO <span class="hljs-string">"verts/C"</span> edges
SHORTEST_PATH <span class="hljs-string">"mps_verts/A"</span> TO <span class="hljs-string">"mps_verts/C"</span> mps_edges
RETURN v
)

View File

@ -1,6 +1,6 @@
@Q:
FOR v, e, p IN <span class="hljs-number">2.</span><span class="hljs-number">.2</span> OUTBOUND <span class="hljs-string">"verts/A"</span> edges
FILTER v._id == <span class="hljs-string">"verts/C"</span>
FOR v, e, p IN <span class="hljs-number">2.</span><span class="hljs-number">.2</span> OUTBOUND <span class="hljs-string">"mps_verts/A"</span> mps_edges
FILTER v._id == <span class="hljs-string">"mps_verts/C"</span>
RETURN CONCAT_SEPARATOR(<span class="hljs-string">" -&gt; "</span>, p.vertices[*]._key)
@R

View File

@ -0,0 +1,96 @@
arangosh&gt; <span class="hljs-keyword">var</span> examples = <span class="hljs-built_in">require</span>(<span class="hljs-string">"@arangodb/graph-examples/example-graph.js"</span>);
arangosh&gt; <span class="hljs-keyword">var</span> g = examples.loadGraph(<span class="hljs-string">"mps_graph"</span>);
arangosh&gt; db.mps_verts.toArray();
[
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"F"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_verts/F"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mK--F"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"A"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_verts/A"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mG--_"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"E"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_verts/E"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mK--D"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"C"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_verts/C"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mK--_"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"D"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_verts/D"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mK--B"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"B"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_verts/B"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mG--B"</span>
}
]
arangosh&gt; db.mps_edges.toArray();
[
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"160"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_edges/160"</span>,
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"mps_verts/F"</span>,
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"mps_verts/C"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-ma--B"</span>,
<span class="hljs-string">"vertex"</span> : <span class="hljs-string">"F"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"141"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_edges/141"</span>,
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"mps_verts/A"</span>,
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"mps_verts/B"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mS--_"</span>,
<span class="hljs-string">"vertex"</span> : <span class="hljs-string">"A"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"151"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_edges/151"</span>,
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"mps_verts/B"</span>,
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"mps_verts/C"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mW--D"</span>,
<span class="hljs-string">"vertex"</span> : <span class="hljs-string">"B"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"145"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_edges/145"</span>,
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"mps_verts/A"</span>,
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"mps_verts/E"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mW--_"</span>,
<span class="hljs-string">"vertex"</span> : <span class="hljs-string">"A"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"157"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_edges/157"</span>,
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"mps_verts/E"</span>,
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"mps_verts/F"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-ma--_"</span>,
<span class="hljs-string">"vertex"</span> : <span class="hljs-string">"E"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"154"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_edges/154"</span>,
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"mps_verts/D"</span>,
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"mps_verts/C"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mW--F"</span>,
<span class="hljs-string">"vertex"</span> : <span class="hljs-string">"D"</span>
},
{
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"148"</span>,
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"mps_edges/148"</span>,
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"mps_verts/A"</span>,
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"mps_verts/D"</span>,
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"_W7-b-mW--B"</span>,
<span class="hljs-string">"vertex"</span> : <span class="hljs-string">"A"</span>
}
]
arangosh&gt; examples.dropGraph(<span class="hljs-string">"mps_graph"</span>);
<span class="hljs-literal">true</span>

View File

@ -308,7 +308,7 @@ authRouter.get('/query/result/download/:query', function (req, res) {
authRouter.post('/graph-examples/create/:name', function (req, res) {
const name = req.pathParams.name;
if (['knows_graph', 'social', 'routeplanner'].indexOf(name) === -1) {
if (['knows_graph', 'social', 'routeplanner', 'traversalGraph', 'mps_graph', 'worldCountry'].indexOf(name) === -1) {
res.throw('not found');
}

View File

@ -27,7 +27,7 @@
</li>
<li class="enabled">
<a id="loadFullGraph" class="headerButton">
<span title="Download full graph - use with caution">
<span title="Fetch full graph - use with caution">
<i class="fa fa-share-alt"></i>
</span>
</a>

View File

@ -17,6 +17,24 @@
<button style="float: right; margin-bottom: 10px;" graph-id="knows_graph" class="button-success createExampleGraphs">Create</button>
</td>
</tr>
<tr>
<td>Traversal Graph</td>
<td>
<button style="float: right; margin-bottom: 10px;" graph-id="traversalGraph" class="button-success createExampleGraphs">Create</button>
</td>
</tr>
<tr>
<td>Mps Graph</td>
<td>
<button style="float: right; margin-bottom: 10px;" graph-id="mps_graph" class="button-success createExampleGraphs">Create</button>
</td>
</tr>
<tr>
<td>World Graph</td>
<td>
<button style="float: right; margin-bottom: 10px;" graph-id="worldCountry" class="button-success createExampleGraphs">Create</button>
</td>
</tr>
<tr>
<td>Social Graph</td>
<td>
@ -24,7 +42,7 @@
</td>
</tr>
<tr>
<td>Routeplanner Graph</td>
<td>City Graph</td>
<td>
<button style="float: right; margin-bottom: 10px;" graph-id="routeplanner" class="button-success createExampleGraphs">Create</button>
</td>

View File

@ -1,5 +1,3 @@
/* jshint maxlen:160 */
'use strict';
// //////////////////////////////////////////////////////////////////////////////
// / @brief Graph Data for Example
@ -52,24 +50,24 @@ var createTraversalExample = function () {
return g;
};
// we create a graph with 'edges' pointing from 'verts' to 'verts'
// we create a graph with 'edges2' pointing from 'verts' to 'verts'
var createMpsTraversal = function () {
var g = Graph._create('mps_graph',
[Graph._relation('edges', 'verts', 'verts')]
[Graph._relation('mps_edges', 'mps_verts', 'mps_verts')]
);
var a = g.verts.save({_key: 'A'});
var b = g.verts.save({_key: 'B'});
var c = g.verts.save({_key: 'C'});
var d = g.verts.save({_key: 'D'});
var e = g.verts.save({_key: 'E'});
var f = g.verts.save({_key: 'F'});
g.edges.save(a._id, b._id, {vertex:a._key});
g.edges.save(a._id, e._id, {vertex:a._key});
g.edges.save(a._id, d._id, {vertex:a._key});
g.edges.save(b._id, c._id, {vertex:b._key});
g.edges.save(d._id, c._id, {vertex:d._key});
g.edges.save(e._id, f._id, {vertex:e._key});
g.edges.save(f._id, c._id, {vertex:f._key});
var a = g.mps_verts.save({_key: 'A'});
var b = g.mps_verts.save({_key: 'B'});
var c = g.mps_verts.save({_key: 'C'});
var d = g.mps_verts.save({_key: 'D'});
var e = g.mps_verts.save({_key: 'E'});
var f = g.mps_verts.save({_key: 'F'});
g.mps_edges.save(a._id, b._id, {vertex:a._key});
g.mps_edges.save(a._id, e._id, {vertex:a._key});
g.mps_edges.save(a._id, d._id, {vertex:a._key});
g.mps_edges.save(b._id, c._id, {vertex:b._key});
g.mps_edges.save(d._id, c._id, {vertex:d._key});
g.mps_edges.save(e._id, f._id, {vertex:e._key});
g.mps_edges.save(f._id, c._id, {vertex:f._key});
return g;
};
@ -398,7 +396,7 @@ var knownGraphs = {
'knows', 'persons'
]},
'mps_graph': {create: createMpsTraversal, dependencies: [
'edges', 'verts'
'mps_edges', 'mps_verts'
]},
'routeplanner': {create: createRoutePlannerGraph, dependencies: [
'frenchHighway', 'frenchCity', 'germanCity', 'germanHighway', 'internationalHighway'