1
0
Fork 0

Doc - Fix/improve graph traversal/background indexing pages, console.history and examples/options (#8336)

This commit is contained in:
Simran 2019-03-11 14:06:28 +01:00 committed by GitHub
parent 12e11a5197
commit 8891f79356
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 380 additions and 283 deletions

View File

@ -57,7 +57,7 @@ FOR vertex[, edge[, path]]
the search will not continue from this path, namely there will be no
result having this path as a prefix.
e.g.: Take the path: `(A) -> (B) -> (C)` starting at `A` and PRUNE on `B`
will result in `(A)` and `(A) -> (B)` beeing valid paths, and `(A) -> (B) -> (C)`
will result in `(A)` and `(A) -> (B)` being valid paths, and `(A) -> (B) -> (C)`
not returned, it got pruned on B.
* If the condition evaluates to `false` we will continue our search beyond
this path.
@ -67,6 +67,12 @@ FOR vertex[, edge[, path]]
as well as all variables defined before this Traversal statement.
- `OPTIONS` **options** (object, *optional*): used to modify the execution of the
traversal. Only the following attributes have an effect, all others are ignored:
- **bfs** (bool): optionally use the alternative breadth-first traversal algorithm
- true the traversal will be executed breadth-first. The results will first
contain all vertices at depth 1. Than all vertices at depth 2 and so on.
- false (default) the traversal will be executed depth-first. It will first
return all paths from *min* depth to *max* depth for one vertex at depth 1.
Than for the next vertex at depth 1 and so on.
- **uniqueVertices** (string): optionally ensure vertex uniqueness
- "path" it is guaranteed that there is no path returned with a duplicate vertex
- "global" it is guaranteed that each vertex is visited at most once during
@ -75,18 +81,14 @@ FOR vertex[, edge[, path]]
might not be returned at all (it still might be part of a path). **Note:**
Using this configuration the result is not deterministic any more. If there
are multiple paths from *startVertex* to *vertex*, one of those is picked.
It is required to set `bfs: true` because with depth-first search the results
would be unpredictable.
- "none" (default) no uniqueness check is applied on vertices
- **uniqueEdges** (string): optionally ensure edge uniqueness
- "path" (default) it is guaranteed that there is no path returned with a
duplicate edge
- "none" no uniqueness check is applied on edges. **Note:**
Using this configuration the traversal will follow cycles in edges.
- **bfs** (bool): optionally use the alternative breadth-first traversal algorithm
- true the traversal will be executed breadth-first. The results will first
contain all vertices at depth 1. Than all vertices at depth 2 and so on.
- false (default) the traversal will be executed depth-first. It will first
return all paths from *min* depth to *max* depth for one vertex at depth 1.
Than for the next vertex at depth 1 and so on.
Using this configuration the traversal will follow edges in cycles.
### Working with collection sets
@ -156,7 +158,9 @@ combined filters cannot.
The following examples are based on the [traversal graph](../../Manual/Graphs/index.html#the-traversal-graph).
### Pruning (since version 3.4.5)
### Pruning
<small>Introduced in: v3.4.5</small>
Pruning is the easiest variant to formulate conditions to reduce the amount of data
to be checked during a search. So it allows to improve query performance and reduces
@ -165,7 +169,7 @@ vertex, the edge and the path and any variable defined before.
See examples:
@startDocuBlockInline GRAPHTRAV_graphPruneEdges
@EXAMPLE_AQL{GRAPHTRAV_graphFilterEdges}
@EXAMPLE_AQL{GRAPHTRAV_graphPruneEdges}
@DATASET{traversalGraph}
FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
PRUNE e.theTruth == true
@ -173,14 +177,14 @@ See examples:
@END_EXAMPLE_AQL
@endDocuBlock GRAPHTRAV_graphPruneEdges
This will search until it sees an edge having `theTruth == true`.
The path with this edge will be returned, the search will not
continue after this edge.
Namely all responses either have no edge with `theTruth == true`
or the last edge on the path has `theTruth == true`.
This will search until it sees an edge having `theTruth == true`.
The path with this edge will be returned, the search will not
continue after this edge.
Namely all responses either have no edge with `theTruth == true`
or the last edge on the path has `theTruth == true`.
@startDocuBlockInline GRAPHTRAV_graphPruneVertices
@EXAMPLE_AQL{GRAPHTRAV_graphFilterEdges}
@EXAMPLE_AQL{GRAPHTRAV_graphPruneVertices}
@DATASET{traversalGraph}
FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
PRUNE v._key == 'G'
@ -189,18 +193,18 @@ See examples:
@END_EXAMPLE_AQL
@endDocuBlock GRAPHTRAV_graphPruneVertices
This will search for all paths from the source `circles/A` to the vertex `circles/G`.
This is done with first the PRUNE which makes sure we stop search as soon as we have found
`G` and we will not go beyond `G` and via a loop return to it.
With the second filter, we remove all paths that do not end in `G` namely
all shorter ones that have not been cut out by prune.
Hence the list of all paths from `A` to `G` are returned.
This will search for all paths from the source `circles/A` to the vertex `circles/G`.
This is done with first the PRUNE which makes sure we stop search as soon as we have found
`G` and we will not go beyond `G` and via a loop return to it.
With the second filter, we remove all paths that do not end in `G` namely
all shorter ones that have not been cut out by prune.
Hence the list of all paths from `A` to `G` are returned.
Note you can also prune as soon as you reach a certain collection with the following
example:
@startDocuBlockInline GRAPHTRAV_graphPruneCollection
@EXAMPLE_AQL{GRAPHTRAV_graphFilterEdges}
@EXAMPLE_AQL{GRAPHTRAV_graphPruneCollection}
@DATASET{traversalGraph}
FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
PRUNE IS_SAME_COLLECTION('circles', v)
@ -315,7 +319,7 @@ All of the above filters can be defined on vertices in the exact same way.
Filtering on the path influences the Iteration on your graph. If certain conditions
aren't met, the traversal may stop continuing along this path.
In contrast filters on vertex or edge only express whether you're interestet in the actual value of these
In contrast filters on vertex or edge only express whether you're interested in the actual value of these
documents. Thus, it influences the list of returned documents (if you return v or e) similar
as specifying a non-null `min` value. If you specify a min value of 2, the traversal over the first
two nodes of these paths has to be executed - you just won't see them in your result array.
@ -323,7 +327,6 @@ two nodes of these paths has to be executed - you just won't see them in your re
Similar are filters on vertices or edges - the traverser has to walk along these nodes, since
you may be interested in documents further down the path.
### Examples
We will create a simple symmetric traversal demonstration graph:
@ -399,14 +402,18 @@ side of the graph, we may filter in two ways:
@startDocuBlockInline GRAPHTRAV_04_traverse_4a
@EXAMPLE_AQL{GRAPHTRAV_04_traverse_4a}
@DATASET{traversalGraph}
FOR v, e, p IN 1..3 OUTBOUND 'circles/A' GRAPH 'traversalGraph' FILTER p.vertices[1]._key != 'G' RETURN v._key
FOR v, e, p IN 1..3 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
FILTER p.vertices[1]._key != 'G'
RETURN v._key
@END_EXAMPLE_AQL
@endDocuBlock GRAPHTRAV_04_traverse_4a
@startDocuBlockInline GRAPHTRAV_04_traverse_4b
@EXAMPLE_AQL{GRAPHTRAV_04_traverse_4b}
@DATASET{traversalGraph}
FOR v, e, p IN 1..3 OUTBOUND 'circles/A' GRAPH 'traversalGraph' FILTER p.edges[0].label != 'right_foo' RETURN v._key
FOR v, e, p IN 1..3 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
FILTER p.edges[0].label != 'right_foo'
RETURN v._key
@END_EXAMPLE_AQL
@endDocuBlock GRAPHTRAV_04_traverse_4b
@ -502,7 +509,6 @@ traversal queries using [the explainer](../ExecutionAndPerformance/Optimizer.md)
@END_EXAMPLE_AQL
@endDocuBlock GRAPHTRAV_07_traverse_7
@startDocuBlockInline GRAPHTRAV_07_traverse_8
@EXAMPLE_AQL{GRAPHTRAV_07_traverse_8}
@DATASET{traversalGraph}
@ -530,7 +536,6 @@ And finally clean it up again:
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock GRAPHTRAV_99_drop_graph
If this traversal is not powerful enough for your needs, like you cannot describe
your conditions as AQL filter statements, then you might want to have a look at
[manually crafted traversers](../../Manual/Graphs/Traversals/index.html).

View File

@ -26,7 +26,7 @@ Creating new indexes is by default done under an exclusive collection lock. The
available while the index is being created. This "foreground" index creation can be undesirable,
if you have to perform it on a live system without a dedicated maintenance window.
For potentially long running index creation operations the _rocksdb_ storage-engine also supports
For potentially long running index creation operations the _RocksDB_ storage-engine also supports
creating indexes in "background". The collection remains (mostly) available during the index creation,
see the section [Creating Indexes in Background](#creating-indexes-in-background) for more information.
@ -607,8 +607,10 @@ for highly connected graphs and with RocksDB storage engine.
Creating Indexes in Background
------------------------------
<small>Introduced in: v3.5.0</small>
{% hint 'info' %}
This section only applies to the *rocksdb* storage engine
Background indexing is available for the *RocksDB* storage engine only.
{% endhint %}
Creating new indexes is by default done under an exclusive collection lock. This means
@ -616,7 +618,7 @@ that the collection (or the respective shards) are not available for write opera
as long as the index is created. This "foreground" index creation can be undesirable,
if you have to perform it on a live system without a dedicated maintenance window.
**STARTING FROM VERSION v3.5.0**, indexes can also be created in "background", not using an
Indexes can also be created in "background", not using an
exclusive lock during the entire index creation. The collection remains basically available,
so that other CRUD operations can run on the collection while the index is being created.
This can be achieved by setting the *inBackground* attribute when creating an index.
@ -651,7 +653,8 @@ work as before.
{% hint 'info' %}
Should you be building an index in the background you cannot rename or drop the collection.
These operations will block until the index creation is finished.
These operations will block until the index creation is finished. This is equally the case
with foreground indexing.
{% endhint %}
After an interrupted index build (i.e. due to a server crash) the partially built index

View File

@ -85,8 +85,8 @@ client programs can thus safely set the *inBackground* option to *true* and cont
work as before.
Should you be building an index in the background you cannot rename or drop the collection.
These operations will block until the index creation is finished.
{% endhint %}
These operations will block until the index creation is finished. This is equally the case
with foreground indexing.
After an interrupted index build (i.e. due to a server crash) the partially built index
will the removed. In the ArangoDB cluster the index might then be automatically recreated

View File

@ -5,171 +5,171 @@ arangosh&gt; db.circles.toArray();
{
"_key" : "I",
"_id" : "circles/I",
"_rev" : "_YOn1Fju--J",
"_rev" : "_YT2FO_e--_",
"label" : "9"
},
{
"_key" : "G",
"_id" : "circles/G",
"_rev" : "_YOn1Fju--F",
"_rev" : "_YT2FO_a--B",
"label" : "7"
},
{
"_key" : "F",
"_id" : "circles/F",
"_rev" : "_YOn1Fju--D",
"_rev" : "_YT2FO_a--_",
"label" : "6"
},
{
"_key" : "A",
"_id" : "circles/A",
"_rev" : "_YOn1Fjq--_",
"_rev" : "_YT2FO_S--_",
"label" : "1"
},
{
"_key" : "E",
"_id" : "circles/E",
"_rev" : "_YOn1Fju--B",
"_rev" : "_YT2FO_W--B",
"label" : "5"
},
{
"_key" : "C",
"_id" : "circles/C",
"_rev" : "_YOn1Fjq--D",
"_rev" : "_YT2FO_S--D",
"label" : "3"
},
{
"_key" : "D",
"_id" : "circles/D",
"_rev" : "_YOn1Fju--_",
"_rev" : "_YT2FO_W--_",
"label" : "4"
},
{
"_key" : "J",
"_id" : "circles/J",
"_rev" : "_YOn1Fjy--_",
"_rev" : "_YT2FO_e--B",
"label" : "10"
},
{
"_key" : "B",
"_id" : "circles/B",
"_rev" : "_YOn1Fjq--B",
"_rev" : "_YT2FO_S--B",
"label" : "2"
},
{
"_key" : "H",
"_id" : "circles/H",
"_rev" : "_YOn1Fju--H",
"_rev" : "_YT2FO_a--D",
"label" : "8"
},
{
"_key" : "K",
"_id" : "circles/K",
"_rev" : "_YOn1Fjy--B",
"_rev" : "_YT2FO_e--D",
"label" : "11"
}
]
arangosh&gt; db.edges.toArray();
[
{
"_key" : "98585",
"_id" : "edges/98585",
"_from" : "circles/G",
"_to" : "circles/J",
"_rev" : "_YOn1Fj2--D",
"theFalse" : false,
"theTruth" : true,
"label" : "right_zip"
},
{
"_key" : "98573",
"_id" : "edges/98573",
"_from" : "circles/E",
"_to" : "circles/F",
"_rev" : "_YOn1Fjy--L",
"theFalse" : false,
"theTruth" : true,
"label" : "left_schubi"
},
{
"_key" : "98588",
"_id" : "edges/98588",
"_from" : "circles/J",
"_to" : "circles/K",
"_rev" : "_YOn1Fj2--F",
"theFalse" : false,
"theTruth" : true,
"label" : "right_zup"
},
{
"_key" : "98570",
"_id" : "edges/98570",
"_from" : "circles/B",
"_to" : "circles/E",
"_rev" : "_YOn1Fjy--J",
"theFalse" : false,
"theTruth" : true,
"label" : "left_blub"
},
{
"_key" : "98582",
"_id" : "edges/98582",
"_from" : "circles/H",
"_to" : "circles/I",
"_rev" : "_YOn1Fj2--B",
"theFalse" : false,
"theTruth" : true,
"label" : "right_blub"
},
{
"_key" : "98576",
"_id" : "edges/98576",
"_from" : "circles/A",
"_to" : "circles/G",
"_rev" : "_YOn1Fjy--N",
"theFalse" : false,
"theTruth" : true,
"label" : "right_foo"
},
{
"_key" : "98567",
"_id" : "edges/98567",
"_from" : "circles/C",
"_to" : "circles/D",
"_rev" : "_YOn1Fjy--H",
"theFalse" : false,
"theTruth" : true,
"label" : "left_blorg"
},
{
"_key" : "98579",
"_id" : "edges/98579",
"_from" : "circles/G",
"_to" : "circles/H",
"_rev" : "_YOn1Fj2--_",
"theFalse" : false,
"theTruth" : true,
"label" : "right_blob"
},
{
"_key" : "98564",
"_id" : "edges/98564",
"_key" : "98575",
"_id" : "edges/98575",
"_from" : "circles/B",
"_to" : "circles/C",
"_rev" : "_YOn1Fjy--F",
"_rev" : "_YT2FO_i--B",
"theFalse" : false,
"theTruth" : true,
"label" : "left_blarg"
},
{
"_key" : "98560",
"_id" : "edges/98560",
"_key" : "98581",
"_id" : "edges/98581",
"_from" : "circles/B",
"_to" : "circles/E",
"_rev" : "_YT2FO_m--B",
"theFalse" : false,
"theTruth" : true,
"label" : "left_blub"
},
{
"_key" : "98584",
"_id" : "edges/98584",
"_from" : "circles/E",
"_to" : "circles/F",
"_rev" : "_YT2FO_m--D",
"theFalse" : false,
"theTruth" : true,
"label" : "left_schubi"
},
{
"_key" : "98599",
"_id" : "edges/98599",
"_from" : "circles/J",
"_to" : "circles/K",
"_rev" : "_YT2FO_u--B",
"theFalse" : false,
"theTruth" : true,
"label" : "right_zup"
},
{
"_key" : "98596",
"_id" : "edges/98596",
"_from" : "circles/G",
"_to" : "circles/J",
"_rev" : "_YT2FO_u--_",
"theFalse" : false,
"theTruth" : true,
"label" : "right_zip"
},
{
"_key" : "98593",
"_id" : "edges/98593",
"_from" : "circles/H",
"_to" : "circles/I",
"_rev" : "_YT2FO_q--D",
"theFalse" : false,
"theTruth" : true,
"label" : "right_blub"
},
{
"_key" : "98587",
"_id" : "edges/98587",
"_from" : "circles/A",
"_to" : "circles/G",
"_rev" : "_YT2FO_q--_",
"theFalse" : false,
"theTruth" : true,
"label" : "right_foo"
},
{
"_key" : "98571",
"_id" : "edges/98571",
"_from" : "circles/A",
"_to" : "circles/B",
"_rev" : "_YOn1Fjy--D",
"_rev" : "_YT2FO_i--_",
"theFalse" : false,
"theTruth" : true,
"label" : "left_bar"
},
{
"_key" : "98578",
"_id" : "edges/98578",
"_from" : "circles/C",
"_to" : "circles/D",
"_rev" : "_YT2FO_m--_",
"theFalse" : false,
"theTruth" : true,
"label" : "left_blorg"
},
{
"_key" : "98590",
"_id" : "edges/98590",
"_from" : "circles/G",
"_to" : "circles/H",
"_rev" : "_YT2FO_q--B",
"theFalse" : false,
"theTruth" : true,
"label" : "right_blob"
}
]
arangosh&gt; print("once you don't need them anymore, clean them up:");

View File

@ -1,5 +1,7 @@
@Q:
FOR v, e, p IN <span class="hljs-number">1.</span><span class="hljs-number">.3</span> OUTBOUND <span class="hljs-string">'circles/A'</span> GRAPH <span class="hljs-string">'traversalGraph'</span> FILTER p.vertices[<span class="hljs-number">1</span>]._key != <span class="hljs-string">'G'</span> RETURN v._key
FOR v, e, p IN <span class="hljs-number">1.</span><span class="hljs-number">.3</span> OUTBOUND <span class="hljs-string">'circles/A'</span> GRAPH <span class="hljs-string">'traversalGraph'</span>
FILTER p.vertices[<span class="hljs-number">1</span>]._key != <span class="hljs-string">'G'</span>
RETURN v._key
@R
[

View File

@ -1,5 +1,7 @@
@Q:
FOR v, e, p IN <span class="hljs-number">1.</span><span class="hljs-number">.3</span> OUTBOUND <span class="hljs-string">'circles/A'</span> GRAPH <span class="hljs-string">'traversalGraph'</span> FILTER p.edges[<span class="hljs-number">0</span>].label != <span class="hljs-string">'right_foo'</span> RETURN v._key
FOR v, e, p IN <span class="hljs-number">1.</span><span class="hljs-number">.3</span> OUTBOUND <span class="hljs-string">'circles/A'</span> GRAPH <span class="hljs-string">'traversalGraph'</span>
FILTER p.edges[<span class="hljs-number">0</span>].label != <span class="hljs-string">'right_foo'</span>
RETURN v._key
@R
[

View File

@ -5,38 +5,38 @@
RETURN v._key
@R
<span style="color:rgb(85,85,255)">Query String:</span>
<span style="color:rgb(0,187,0)"> FOR v,e,p IN 1..3 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
Query String:
FOR v,e,p IN 1..3 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
LET localScopeVar = RAND() &gt; 0.5
FILTER p.edges[0].theTruth != localScopeVar
RETURN v._key
</span>
<span style="color:rgb(85,85,255)">Execution plan:</span>
<span style="color:rgb(187,0,187)">Id</span> <span style="color:rgb(187,0,187)">NodeType</span> <span style="color:rgb(187,0,187)">Est.</span> <span style="color:rgb(187,0,187)">Comment</span>
<span style="color:rgb(187,187,0)">1</span> <span style="color:rgb(0,187,187)">SingletonNode</span> <span style="color:rgb(0,187,0)">1</span> * <span style="color:rgb(0,187,187)">ROOT</span>
<span style="color:rgb(187,187,0)">2</span> <span style="color:rgb(0,187,187)">TraversalNode</span> <span style="color:rgb(0,187,0)">1</span> - <span style="color:rgb(0,187,187)">FOR </span><span style="color:rgb(187,187,0)">v</span> <span style="color:rgb(0,0,187)">/* vertex */</span>, <span style="color:rgb(187,187,0)">p</span> <span style="color:rgb(0,0,187)">/* paths */</span> <span style="color:rgb(0,187,187)">IN</span> <span style="color:rgb(0,187,0)">1..3</span> <span style="color:rgb(0,0,187)">/* min..maxPathDepth */</span> <span style="color:rgb(0,187,187)">OUTBOUND</span> '<span style="color:rgb(0,187,0)">circles/A</span>' <span style="color:rgb(0,0,187)">/* startnode */</span> <span style="color:rgb(0,187,187)">GRAPH</span> '<span style="color:rgb(0,187,0)">traversalGraph</span>'
<span style="color:rgb(187,187,0)">3</span> <span style="color:rgb(0,187,187)">CalculationNode</span> <span style="color:rgb(0,187,0)">1</span> - <span style="color:rgb(0,187,187)">LET</span> <span style="color:rgb(187,187,0)">localScopeVar</span> = (<span style="color:rgb(0,187,0)">RAND</span>() &gt; <span style="color:rgb(0,187,0)">0.5</span>) <span style="color:rgb(0,0,187)">/* simple expression */</span>
<span style="color:rgb(187,187,0)">4</span> <span style="color:rgb(0,187,187)">CalculationNode</span> <span style="color:rgb(0,187,0)">1</span> - <span style="color:rgb(0,187,187)">LET</span> <span style="color:rgb(187,0,187)">#6</span> = (<span style="color:rgb(187,187,0)">p</span>.`<span style="color:rgb(187,187,0)">edges</span>`[<span style="color:rgb(0,187,0)">0</span>].`<span style="color:rgb(187,187,0)">theTruth</span>` != <span style="color:rgb(187,187,0)">localScopeVar</span>) <span style="color:rgb(0,0,187)">/* simple expression */</span>
<span style="color:rgb(187,187,0)">5</span> <span style="color:rgb(0,187,187)">FilterNode</span> <span style="color:rgb(0,187,0)">1</span> - <span style="color:rgb(0,187,187)">FILTER</span> <span style="color:rgb(187,0,187)">#6</span>
<span style="color:rgb(187,187,0)">6</span> <span style="color:rgb(0,187,187)">CalculationNode</span> <span style="color:rgb(0,187,0)">1</span> - <span style="color:rgb(0,187,187)">LET</span> <span style="color:rgb(187,0,187)">#8</span> = <span style="color:rgb(187,187,0)">v</span>.`<span style="color:rgb(187,187,0)">_key</span>` <span style="color:rgb(0,0,187)">/* attribute expression */</span>
<span style="color:rgb(187,187,0)">7</span> <span style="color:rgb(0,187,187)">ReturnNode</span> <span style="color:rgb(0,187,0)">1</span> - <span style="color:rgb(0,187,187)">RETURN</span> <span style="color:rgb(187,0,187)">#8</span>
<span style="color:rgb(85,85,255)">Indexes used:</span>
<span style="color:rgb(187,0,187)">By</span> <span style="color:rgb(187,0,187)">Type</span> <span style="color:rgb(187,0,187)">Collection</span> <span style="color:rgb(187,0,187)">Unique</span> <span style="color:rgb(187,0,187)">Sparse</span> <span style="color:rgb(187,0,187)">Selectivity</span> <span style="color:rgb(187,0,187)">Fields</span> <span style="color:rgb(187,0,187)">Ranges</span>
<span style="color:rgb(187,187,0)">2</span> <span style="color:rgb(0,187,187)">edge</span> <span style="color:rgb(187,0,0)">edges</span> <span style="color:rgb(0,187,0)">false</span> <span style="color:rgb(0,187,0)">false</span> <span style="color:rgb(0,187,0)">n/a</span> [ `<span style="color:rgb(187,187,0)">_from</span>`, `<span style="color:rgb(187,187,0)">_to</span>` ] <span style="color:rgb(0,187,187)">base OUTBOUND</span>
Execution plan:
Id NodeType Est. Comment
1 SingletonNode 1 * ROOT
2 TraversalNode 1 - FOR v /* vertex */, p /* paths */ IN 1..3 /* min..maxPathDepth */ OUTBOUND 'circles/A' /* startnode */ GRAPH 'traversalGraph'
3 CalculationNode 1 - LET localScopeVar = (RAND() &gt; 0.5) /* simple expression */
4 CalculationNode 1 - LET #6 = (p.`edges`[0].`theTruth` != localScopeVar) /* simple expression */
5 FilterNode 1 - FILTER #6
6 CalculationNode 1 - LET #8 = v.`_key` /* attribute expression */
7 ReturnNode 1 - RETURN #8
<span style="color:rgb(85,85,255)">Functions used:</span>
<span style="color:rgb(187,0,187)">Name</span> <span style="color:rgb(187,0,187)">Deterministic</span> <span style="color:rgb(187,0,187)">Cacheable</span> <span style="color:rgb(187,0,187)">Uses V8</span>
<span style="color:rgb(187,187,0)">RAND</span> <span style="color:rgb(0,187,0)">false</span> <span style="color:rgb(0,187,0)">false</span> <span style="color:rgb(0,187,0)">false</span>
Indexes used:
By Type Collection Unique Sparse Selectivity Fields Ranges
2 edge edges false false n/a [ `_from`, `_to` ] base OUTBOUND
<span style="color:rgb(85,85,255)">Traversals on graphs:</span>
<span style="color:rgb(187,0,187)">Id</span> <span style="color:rgb(187,0,187)">Depth</span> <span style="color:rgb(187,0,187)">Vertex collections</span> <span style="color:rgb(187,0,187)">Edge collections</span> <span style="color:rgb(187,0,187)">Options</span> <span style="color:rgb(187,0,187)">Filter conditions</span>
2 1..3 <span style="color:rgb(187,0,0)">circles</span> <span style="color:rgb(187,0,0)">edges</span> <span style="color:rgb(0,187,187)">uniqueVertices</span>: <span style="color:rgb(0,187,0)">none</span>, <span style="color:rgb(0,187,187)">uniqueEdges</span>: <span style="color:rgb(0,187,0)">path</span>
Functions used:
Name Deterministic Cacheable Uses V8
RAND false false false
<span style="color:rgb(85,85,255)">Optimization rules applied:</span>
<span style="color:rgb(187,0,187)">Id</span> <span style="color:rgb(187,0,187)">RuleName</span>
<span style="color:rgb(187,187,0)">1</span> <span style="color:rgb(0,187,187)">move-calculations-up</span>
<span style="color:rgb(187,187,0)">2</span> <span style="color:rgb(0,187,187)">optimize-traversals</span>
<span style="color:rgb(187,187,0)">3</span> <span style="color:rgb(0,187,187)">move-calculations-down</span>
Traversals on graphs:
Id Depth Vertex collections Edge collections Options Filter / Prune Conditions
2 1..3 circles edges uniqueVertices: none, uniqueEdges: path
Optimization rules applied:
Id RuleName
1 move-calculations-up
2 optimize-traversals
3 move-calculations-down

View File

@ -4,36 +4,36 @@
RETURN v._key
@R
<span style="color:rgb(85,85,255)">Query String:</span>
<span style="color:rgb(0,187,0)"> FOR v,e,p IN 1..3 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
Query String:
FOR v,e,p IN 1..3 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
FILTER p.edges[0].label == 'right_foo'
RETURN v._key
</span>
<span style="color:rgb(85,85,255)">Execution plan:</span>
<span style="color:rgb(187,0,187)">Id</span> <span style="color:rgb(187,0,187)">NodeType</span> <span style="color:rgb(187,0,187)">Est.</span> <span style="color:rgb(187,0,187)">Comment</span>
<span style="color:rgb(187,187,0)">1</span> <span style="color:rgb(0,187,187)">SingletonNode</span> <span style="color:rgb(0,187,0)">1</span> * <span style="color:rgb(0,187,187)">ROOT</span>
<span style="color:rgb(187,187,0)">2</span> <span style="color:rgb(0,187,187)">TraversalNode</span> <span style="color:rgb(0,187,0)">1</span> - <span style="color:rgb(0,187,187)">FOR </span><span style="color:rgb(187,187,0)">v</span> <span style="color:rgb(0,0,187)">/* vertex */</span> <span style="color:rgb(0,187,187)">IN</span> <span style="color:rgb(0,187,0)">1..3</span> <span style="color:rgb(0,0,187)">/* min..maxPathDepth */</span> <span style="color:rgb(0,187,187)">OUTBOUND</span> '<span style="color:rgb(0,187,0)">circles/A</span>' <span style="color:rgb(0,0,187)">/* startnode */</span> <span style="color:rgb(0,187,187)">GRAPH</span> '<span style="color:rgb(0,187,0)">traversalGraph</span>'
<span style="color:rgb(187,187,0)">5</span> <span style="color:rgb(0,187,187)">CalculationNode</span> <span style="color:rgb(0,187,0)">1</span> - <span style="color:rgb(0,187,187)">LET</span> <span style="color:rgb(187,0,187)">#7</span> = <span style="color:rgb(187,187,0)">v</span>.`<span style="color:rgb(187,187,0)">_key</span>` <span style="color:rgb(0,0,187)">/* attribute expression */</span>
<span style="color:rgb(187,187,0)">6</span> <span style="color:rgb(0,187,187)">ReturnNode</span> <span style="color:rgb(0,187,0)">1</span> - <span style="color:rgb(0,187,187)">RETURN</span> <span style="color:rgb(187,0,187)">#7</span>
<span style="color:rgb(85,85,255)">Indexes used:</span>
<span style="color:rgb(187,0,187)">By</span> <span style="color:rgb(187,0,187)">Type</span> <span style="color:rgb(187,0,187)">Collection</span> <span style="color:rgb(187,0,187)">Unique</span> <span style="color:rgb(187,0,187)">Sparse</span> <span style="color:rgb(187,0,187)">Selectivity</span> <span style="color:rgb(187,0,187)">Fields</span> <span style="color:rgb(187,0,187)">Ranges</span>
<span style="color:rgb(187,187,0)">2</span> <span style="color:rgb(0,187,187)">edge</span> <span style="color:rgb(187,0,0)">edges</span> <span style="color:rgb(0,187,0)">false</span> <span style="color:rgb(0,187,0)">false</span> <span style="color:rgb(0,187,0)">n/a</span> [ `<span style="color:rgb(187,187,0)">_from</span>`, `<span style="color:rgb(187,187,0)">_to</span>` ] <span style="color:rgb(0,187,187)">base OUTBOUND</span>
<span style="color:rgb(187,187,0)">2</span> <span style="color:rgb(0,187,187)">edge</span> <span style="color:rgb(187,0,0)">edges</span> <span style="color:rgb(0,187,0)">false</span> <span style="color:rgb(0,187,0)">false</span> <span style="color:rgb(0,187,0)">n/a</span> [ `<span style="color:rgb(187,187,0)">_from</span>`, `<span style="color:rgb(187,187,0)">_to</span>` ] <span style="color:rgb(0,187,187)">level 0 OUTBOUND</span>
Execution plan:
Id NodeType Est. Comment
1 SingletonNode 1 * ROOT
2 TraversalNode 1 - FOR v /* vertex */ IN 1..3 /* min..maxPathDepth */ OUTBOUND 'circles/A' /* startnode */ GRAPH 'traversalGraph'
5 CalculationNode 1 - LET #7 = v.`_key` /* attribute expression */
6 ReturnNode 1 - RETURN #7
<span style="color:rgb(85,85,255)">Traversals on graphs:</span>
<span style="color:rgb(187,0,187)">Id</span> <span style="color:rgb(187,0,187)">Depth</span> <span style="color:rgb(187,0,187)">Vertex collections</span> <span style="color:rgb(187,0,187)">Edge collections</span> <span style="color:rgb(187,0,187)">Options</span> <span style="color:rgb(187,0,187)">Filter conditions</span>
2 1..3 <span style="color:rgb(187,0,0)">circles</span> <span style="color:rgb(187,0,0)">edges</span> <span style="color:rgb(0,187,187)">uniqueVertices</span>: <span style="color:rgb(0,187,0)">none</span>, <span style="color:rgb(0,187,187)">uniqueEdges</span>: <span style="color:rgb(0,187,0)">path</span> (<span style="color:rgb(187,187,0)">p</span>.`<span style="color:rgb(187,187,0)">edges</span>`[<span style="color:rgb(0,187,0)">0</span>].`<span style="color:rgb(187,187,0)">label</span>` == <span style="color:rgb(0,187,0)">"right_foo"</span>)
Indexes used:
By Type Collection Unique Sparse Selectivity Fields Ranges
2 edge edges false false n/a [ `_from`, `_to` ] base OUTBOUND
2 edge edges false false n/a [ `_from`, `_to` ] level 0 OUTBOUND
<span style="color:rgb(85,85,255)">Optimization rules applied:</span>
<span style="color:rgb(187,0,187)">Id</span> <span style="color:rgb(187,0,187)">RuleName</span>
<span style="color:rgb(187,187,0)">1</span> <span style="color:rgb(0,187,187)">move-calculations-up</span>
<span style="color:rgb(187,187,0)">2</span> <span style="color:rgb(0,187,187)">move-filters-up</span>
<span style="color:rgb(187,187,0)">3</span> <span style="color:rgb(0,187,187)">move-calculations-up-2</span>
<span style="color:rgb(187,187,0)">4</span> <span style="color:rgb(0,187,187)">move-filters-up-2</span>
<span style="color:rgb(187,187,0)">5</span> <span style="color:rgb(0,187,187)">optimize-traversals</span>
<span style="color:rgb(187,187,0)">6</span> <span style="color:rgb(0,187,187)">remove-filter-covered-by-traversal</span>
<span style="color:rgb(187,187,0)">7</span> <span style="color:rgb(0,187,187)">remove-unnecessary-calculations-2</span>
<span style="color:rgb(187,187,0)">8</span> <span style="color:rgb(0,187,187)">remove-redundant-path-var</span>
Traversals on graphs:
Id Depth Vertex collections Edge collections Options Filter / Prune Conditions
2 1..3 circles edges uniqueVertices: none, uniqueEdges: path FILTER (p.`edges`[0].`label` == "right_foo")
Optimization rules applied:
Id RuleName
1 move-calculations-up
2 move-filters-up
3 move-calculations-up-2
4 move-filters-up-2
5 optimize-traversals
6 remove-filter-covered-by-traversal
7 remove-unnecessary-calculations-2
8 remove-redundant-path-var

View File

@ -0,0 +1,7 @@
@Q:
FOR v, e, p IN <span class="hljs-number">1.</span><span class="hljs-number">.5</span> OUTBOUND <span class="hljs-string">'circles/A'</span> GRAPH <span class="hljs-string">'traversalGraph'</span>
PRUNE IS_SAME_COLLECTION(<span class="hljs-string">'circles'</span>, v)
RETURN { <span class="hljs-attr">vertices</span>: p.vertices[*]._key, <span class="hljs-attr">edges</span>: p.edges[*].label }
@R
[]

View File

@ -0,0 +1,26 @@
@Q:
FOR v, e, p IN <span class="hljs-number">1.</span><span class="hljs-number">.5</span> OUTBOUND <span class="hljs-string">'circles/A'</span> GRAPH <span class="hljs-string">'traversalGraph'</span>
PRUNE e.theTruth == <span class="hljs-literal">true</span>
RETURN { <span class="hljs-attr">vertices</span>: p.vertices[*]._key, <span class="hljs-attr">edges</span>: p.edges[*].label }
@R
[
{
<span class="hljs-string">"vertices"</span>: [
<span class="hljs-string">"A"</span>,
<span class="hljs-string">"B"</span>
],
<span class="hljs-string">"edges"</span>: [
<span class="hljs-string">"left_bar"</span>
]
},
{
<span class="hljs-string">"vertices"</span>: [
<span class="hljs-string">"A"</span>,
<span class="hljs-string">"G"</span>
],
<span class="hljs-string">"edges"</span>: [
<span class="hljs-string">"right_foo"</span>
]
}
]

View File

@ -0,0 +1,18 @@
@Q:
FOR v, e, p IN <span class="hljs-number">1.</span><span class="hljs-number">.5</span> OUTBOUND <span class="hljs-string">'circles/A'</span> GRAPH <span class="hljs-string">'traversalGraph'</span>
PRUNE v._key == <span class="hljs-string">'G'</span>
FILTER v._key == <span class="hljs-string">'G'</span>
RETURN { <span class="hljs-attr">vertices</span>: p.vertices[*]._key, <span class="hljs-attr">edges</span>: p.edges[*].label }
@R
[
{
<span class="hljs-string">"vertices"</span>: [
<span class="hljs-string">"A"</span>,
<span class="hljs-string">"G"</span>
],
<span class="hljs-string">"edges"</span>: [
<span class="hljs-string">"right_foo"</span>
]
}
]

View File

@ -1,6 +1,6 @@
@Q:
RETURN GEO_LINESTRING([
[<span class="hljs-number">35</span>, <span class="hljs-number">10</span>], [<span class="hljs-number">45</span>, <span class="hljs-number">45</span>]
[<span class="hljs-number">35</span>, <span class="hljs-number">10</span>], [<span class="hljs-number">45</span>, <span class="hljs-number">45</span>]
])
@R

View File

@ -1,6 +1,6 @@
@Q:
RETURN GEO_MULTIPOINT([
[<span class="hljs-number">35</span>, <span class="hljs-number">10</span>], [<span class="hljs-number">45</span>, <span class="hljs-number">45</span>]
[<span class="hljs-number">35</span>, <span class="hljs-number">10</span>], [<span class="hljs-number">45</span>, <span class="hljs-number">45</span>]
])
@R

View File

@ -1,12 +1,12 @@
@Q:
RETURN GEO_MULTIPOLYGON([
[
[
[[<span class="hljs-number">40</span>, <span class="hljs-number">40</span>], [<span class="hljs-number">20</span>, <span class="hljs-number">45</span>], [<span class="hljs-number">45</span>, <span class="hljs-number">30</span>], [<span class="hljs-number">40</span>, <span class="hljs-number">40</span>]]
],
[
],
[
[[<span class="hljs-number">20</span>, <span class="hljs-number">35</span>], [<span class="hljs-number">10</span>, <span class="hljs-number">30</span>], [<span class="hljs-number">10</span>, <span class="hljs-number">10</span>], [<span class="hljs-number">30</span>, <span class="hljs-number">5</span>], [<span class="hljs-number">45</span>, <span class="hljs-number">20</span>], [<span class="hljs-number">20</span>, <span class="hljs-number">35</span>]],
[[<span class="hljs-number">30</span>, <span class="hljs-number">20</span>], [<span class="hljs-number">20</span>, <span class="hljs-number">15</span>], [<span class="hljs-number">20</span>, <span class="hljs-number">25</span>], [<span class="hljs-number">30</span>, <span class="hljs-number">20</span>]]
]
]
])
@R

View File

@ -1,6 +1,6 @@
@Q:
RETURN GEO_POLYGON([
[<span class="hljs-number">0.0</span>, <span class="hljs-number">0.0</span>], [<span class="hljs-number">7.5</span>, <span class="hljs-number">2.5</span>], [<span class="hljs-number">0.0</span>, <span class="hljs-number">5.0</span>]
[<span class="hljs-number">0.0</span>, <span class="hljs-number">0.0</span>], [<span class="hljs-number">7.5</span>, <span class="hljs-number">2.5</span>], [<span class="hljs-number">0.0</span>, <span class="hljs-number">5.0</span>]
])
@R

View File

@ -1,7 +1,7 @@
@Q:
RETURN GEO_POLYGON([
[[<span class="hljs-number">35</span>, <span class="hljs-number">10</span>], [<span class="hljs-number">45</span>, <span class="hljs-number">45</span>], [<span class="hljs-number">15</span>, <span class="hljs-number">40</span>], [<span class="hljs-number">10</span>, <span class="hljs-number">20</span>], [<span class="hljs-number">35</span>, <span class="hljs-number">10</span>]],
[[<span class="hljs-number">20</span>, <span class="hljs-number">30</span>], [<span class="hljs-number">35</span>, <span class="hljs-number">35</span>], [<span class="hljs-number">30</span>, <span class="hljs-number">20</span>], [<span class="hljs-number">20</span>, <span class="hljs-number">30</span>]]
[[<span class="hljs-number">35</span>, <span class="hljs-number">10</span>], [<span class="hljs-number">45</span>, <span class="hljs-number">45</span>], [<span class="hljs-number">15</span>, <span class="hljs-number">40</span>], [<span class="hljs-number">10</span>, <span class="hljs-number">20</span>], [<span class="hljs-number">35</span>, <span class="hljs-number">10</span>]],
[[<span class="hljs-number">20</span>, <span class="hljs-number">30</span>], [<span class="hljs-number">35</span>, <span class="hljs-number">35</span>], [<span class="hljs-number">30</span>, <span class="hljs-number">20</span>], [<span class="hljs-number">20</span>, <span class="hljs-number">30</span>]]
])
@R

View File

@ -83,6 +83,23 @@
"section" : "console",
"type" : "boolean"
},
"console.history" : {
"category" : "option",
"default" : true,
"deprecatedIn" : null,
"description" : "whether or not to load and persist command-line history",
"dynamic" : false,
"enterpriseOnly" : false,
"hidden" : false,
"introducedIn" : [
"v3.4.5",
"v3.5.0"
],
"obsolete" : false,
"requiresValue" : false,
"section" : "console",
"type" : "boolean"
},
"console.pager" : {
"category" : "option",
"default" : false,

View File

@ -83,6 +83,23 @@
"section" : "console",
"type" : "boolean"
},
"console.history" : {
"category" : "option",
"default" : true,
"deprecatedIn" : null,
"description" : "whether or not to load and persist command-line history",
"dynamic" : false,
"enterpriseOnly" : false,
"hidden" : false,
"introducedIn" : [
"v3.4.5",
"v3.5.0"
],
"obsolete" : false,
"requiresValue" : false,
"section" : "console",
"type" : "boolean"
},
"console.pager" : {
"category" : "option",
"default" : false,