1
0
Fork 0

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

This commit is contained in:
Simran 2019-03-13 08:44:09 +01:00 committed by GitHub
parent b5f914f9ef
commit 9d466d3b06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 334 additions and 240 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
@ -180,7 +184,7 @@ See examples:
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'
@ -200,7 +204,7 @@ Note you can also prune as soon as you reach a certain collection with the follo
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

@ -5,88 +5,98 @@ arangosh&gt; db.circles.toArray();
{
"_key" : "I",
"_id" : "circles/I",
"_rev" : "_YQtDXP---F",
"_rev" : "_YT2FO_e--_",
"label" : "9"
},
{
"_key" : "G",
"_id" : "circles/G",
"_rev" : "_YQtDXP---B",
"_rev" : "_YT2FO_a--B",
"label" : "7"
},
{
"_key" : "F",
"_id" : "circles/F",
"_rev" : "_YQtDXP---_",
"_rev" : "_YT2FO_a--_",
"label" : "6"
},
{
"_key" : "A",
"_id" : "circles/A",
"_rev" : "_YQtDXO2--_",
"_rev" : "_YT2FO_S--_",
"label" : "1"
},
{
"_key" : "E",
"_id" : "circles/E",
"_rev" : "_YQtDXO6--F",
"_rev" : "_YT2FO_W--B",
"label" : "5"
},
{
"_key" : "C",
"_id" : "circles/C",
"_rev" : "_YQtDXO6--B",
"_rev" : "_YT2FO_S--D",
"label" : "3"
},
{
"_key" : "D",
"_id" : "circles/D",
"_rev" : "_YQtDXO6--D",
"_rev" : "_YT2FO_W--_",
"label" : "4"
},
{
"_key" : "J",
"_id" : "circles/J",
"_rev" : "_YQtDXPC--_",
"_rev" : "_YT2FO_e--B",
"label" : "10"
},
{
"_key" : "B",
"_id" : "circles/B",
"_rev" : "_YQtDXO6--_",
"_rev" : "_YT2FO_S--B",
"label" : "2"
},
{
"_key" : "H",
"_id" : "circles/H",
"_rev" : "_YQtDXP---D",
"_rev" : "_YT2FO_a--D",
"label" : "8"
},
{
"_key" : "K",
"_id" : "circles/K",
"_rev" : "_YQtDXPC--B",
"_rev" : "_YT2FO_e--D",
"label" : "11"
}
]
arangosh&gt; db.edges.toArray();
[
{
"_key" : "98581",
"_id" : "edges/98581",
"_key" : "98575",
"_id" : "edges/98575",
"_from" : "circles/B",
"_to" : "circles/C",
"_rev" : "_YQtDXPC--F",
"_rev" : "_YT2FO_i--B",
"theFalse" : false,
"theTruth" : true,
"label" : "left_blarg"
},
{
"_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/C",
"_to" : "circles/D",
"_rev" : "_YQtDXPG--_",
"_from" : "circles/E",
"_to" : "circles/F",
"_rev" : "_YT2FO_m--D",
"theFalse" : false,
"theTruth" : true,
"label" : "left_blorg"
@ -94,9 +104,9 @@ arangosh&gt; db.edges.toArray();
{
"_key" : "98599",
"_id" : "edges/98599",
"_from" : "circles/H",
"_to" : "circles/I",
"_rev" : "_YQtDXPK--B",
"_from" : "circles/J",
"_to" : "circles/K",
"_rev" : "_YT2FO_u--B",
"theFalse" : false,
"theTruth" : true,
"label" : "right_blub"
@ -105,18 +115,8 @@ arangosh&gt; db.edges.toArray();
"_key" : "98596",
"_id" : "edges/98596",
"_from" : "circles/G",
"_to" : "circles/H",
"_rev" : "_YQtDXPK--_",
"theFalse" : false,
"theTruth" : true,
"label" : "right_blob"
},
{
"_key" : "98602",
"_id" : "edges/98602",
"_from" : "circles/G",
"_to" : "circles/J",
"_rev" : "_YQtDXPK--D",
"_rev" : "_YT2FO_u--_",
"theFalse" : false,
"theTruth" : true,
"label" : "right_zip"
@ -124,52 +124,52 @@ arangosh&gt; db.edges.toArray();
{
"_key" : "98593",
"_id" : "edges/98593",
"_from" : "circles/H",
"_to" : "circles/I",
"_rev" : "_YT2FO_q--D",
"theFalse" : false,
"theTruth" : true,
"label" : "right_zip"
},
{
"_key" : "98587",
"_id" : "edges/98587",
"_from" : "circles/A",
"_to" : "circles/G",
"_rev" : "_YQtDXPG--F",
"_rev" : "_YT2FO_q--_",
"theFalse" : false,
"theTruth" : true,
"label" : "right_foo"
},
{
"_key" : "98605",
"_id" : "edges/98605",
"_from" : "circles/J",
"_to" : "circles/K",
"_rev" : "_YQtDXPK--F",
"theFalse" : false,
"theTruth" : true,
"label" : "right_zup"
},
{
"_key" : "98587",
"_id" : "edges/98587",
"_from" : "circles/B",
"_to" : "circles/E",
"_rev" : "_YQtDXPG--B",
"theFalse" : false,
"theTruth" : true,
"label" : "left_blub"
},
{
"_key" : "98577",
"_id" : "edges/98577",
"_key" : "98571",
"_id" : "edges/98571",
"_from" : "circles/A",
"_to" : "circles/B",
"_rev" : "_YQtDXPC--D",
"_rev" : "_YT2FO_i--_",
"theFalse" : false,
"theTruth" : true,
"label" : "left_bar"
},
{
"_key" : "98590",
"_id" : "edges/98590",
"_from" : "circles/E",
"_to" : "circles/F",
"_rev" : "_YQtDXPG--D",
"_key" : "98578",
"_id" : "edges/98578",
"_from" : "circles/C",
"_to" : "circles/D",
"_rev" : "_YT2FO_m--_",
"theFalse" : false,
"theTruth" : true,
"label" : "left_schubi"
"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

@ -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,