diff --git a/3.9/generated/Examples/hybridSmartGraphCreateGraphHowTo1_cluster.generated b/3.9/generated/Examples/hybridSmartGraphCreateGraphHowTo1_cluster.generated
new file mode 100644
index 0000000000..7bb525ab39
--- /dev/null
+++ b/3.9/generated/Examples/hybridSmartGraphCreateGraphHowTo1_cluster.generated
@@ -0,0 +1,9 @@
+arangosh> var graph_module = require("@arangodb/smart-graph");
+arangosh> var rel = graph_module._relation("isCustomer", "shop", "customer")
+arangosh> var graph = graph_module._create("myGraph", [rel], [], {satellites: ["shop", "customer"], smartGraphAttribute: "region", numberOfShards: 9});
+arangosh> graph_module._graph("myGraph");
+{[SmartGraph]
+ "isCustomer" : [ArangoCollection 10060, "isCustomer" (type edge, status loaded)],
+ "shop" : [ArangoCollection 10058, "shop" (type document, status loaded)],
+ "customer" : [ArangoCollection 10059, "customer" (type document, status loaded)]
+}
diff --git a/3.9/generated/Examples/hybridSmartGraphCreateGraphHowTo2_cluster.generated b/3.9/generated/Examples/hybridSmartGraphCreateGraphHowTo2_cluster.generated
new file mode 100644
index 0000000000..19d4208b5f
--- /dev/null
+++ b/3.9/generated/Examples/hybridSmartGraphCreateGraphHowTo2_cluster.generated
@@ -0,0 +1,9 @@
+arangosh> var graph_module = require("@arangodb/smart-graph");
+arangosh> var rel = graph_module._relation("isCustomer", "shop", "customer")
+arangosh> var graph = graph_module._create("myGraph", [rel], [], {satellites: ["shop"], smartGraphAttribute: "region", isDisjoint: true, numberOfShards: 9});
+arangosh> graph_module._graph("myGraph");
+{[SmartGraph]
+ "isCustomer" : [ArangoCollection 10079, "isCustomer" (type edge, status loaded)],
+ "shop" : [ArangoCollection 10078, "shop" (type document, status loaded)],
+ "customer" : [ArangoCollection 10068, "customer" (type document, status loaded)]
+}
diff --git a/3.9/graphs-general-graphs-management.md b/3.9/graphs-general-graphs-management.md
index d5f8dfeb71..dcc12da225 100644
--- a/3.9/graphs-general-graphs-management.md
+++ b/3.9/graphs-general-graphs-management.md
@@ -118,6 +118,16 @@ collection in *toVertexCollections*.
{% endarangoshexample %}
{% include arangoshexample.html id=examplevar script=script result=result %}
+### Edge Definition Options
+
+The following edge definition options are supported:
+
+- `satellites` (array):
+ An array of collection names that will be used to create [SatelliteCollections](satellites.html)
+ for a Hybrid (Disjoint) SmartGraph (Enterprise Edition only). Each array element
+ must be a string and a valid collection name. The collection type cannot be
+ modified later.
+
Create a Graph
--------------
@@ -336,17 +346,20 @@ Drop a graph and keep collections:
Modify a Graph definition at runtime
------------------------------------
-After you have created an graph its definition is not immutable.
+After you have created a graph its definition is not immutable.
You can still add, delete or modify edge definitions and vertex collections.
### Extend the Edge Definitions
Add another edge definition to the graph:
-`graph._extendEdgeDefinitions(edgeDefinition)`
+`graph._extendEdgeDefinitions(edgeDefinition, options)`
- `edgeDefinition` (object):
The relation definition to extend the graph
+- `options` (object):
+ Additional options related to the edge definition itself.
+ See [Edge Definition Options](#edge-definition-options).
Extends the edge definitions of a graph. If an orphan collection is used in this
edge definition, it will be removed from the orphanage. If the edge collection of
@@ -374,11 +387,14 @@ graph with different *from* and/or *to* collections an error is thrown.
Modify a relation definition:
-`graph_module._editEdgeDefinitions(edgeDefinition)`
+`graph_module._editEdgeDefinitions(edgeDefinition, options)`
- `edgeDefinition` (object):
The edge definition to replace the existing edge definition with the same
attribute *collection*.
+- `options` (object):
+ Additional options related to the edge definition itself.
+ See [Edge Definition Options](#edge-definition-options).
Edits one relation definition of a graph. The edge definition used as argument will
replace the existing edge definition of the graph which has the same collection.
@@ -470,12 +486,15 @@ orphans, it will be removed from the set of orphan collection automatically.
Add a vertex collection to the graph:
-`graph._addVertexCollection(vertexCollectionName, createCollection)`
+`graph._addVertexCollection(vertexCollectionName, createCollection, options)`
- `vertexCollectionName` (string):
Name of vertex collection.
- `createCollection` (bool, _optional_):
If true the collection will be created if it does not exist. Default: true
+- `options` (object, _optional_):
+ Additional options related to the edge definition itself.
+ See [Edge Definition Options](#edge-definition-options).
Adds a vertex collection to the set of orphan collections of the graph. If the
collection does not exist, it will be created. If it is already used by any edge
diff --git a/3.9/graphs-smart-graphs-management.md b/3.9/graphs-smart-graphs-management.md
index 88533fa4da..c97513d487 100644
--- a/3.9/graphs-smart-graphs-management.md
+++ b/3.9/graphs-smart-graphs-management.md
@@ -57,6 +57,11 @@ enforce the correct sharding.
- `isDisjoint` (bool, optional):
If set to true, a Disjoint SmartGraph will be created. This flag is not
editable after creation. Default: false.
+ - `satellites` (array, optional):
+ An array of collection names that will be used to create
+ [SatelliteCollections](satellites.html) for a Hybrid (Disjoint) SmartGraph.
+ Each array element must be a string and a valid collection name.
+ The collection type cannot be modified later.
The creation of a graph requires the name and some SmartGraph options.
Due to the API `edgeDefinitions` and `orphanCollections` have to be given, but
diff --git a/3.9/graphs-smart-graphs.md b/3.9/graphs-smart-graphs.md
index 774bd25037..8e053ce460 100644
--- a/3.9/graphs-smart-graphs.md
+++ b/3.9/graphs-smart-graphs.md
@@ -71,9 +71,21 @@ overhead. The more subgraphs are touched the more network cost will apply.
However the overall performance is never worse than the same query using a
General Graph.
-Benefits of Disjoint SmartGraphs
+Benefits of Hybrid SmartGraphs
-------------------------------
+Hybrid SmartGraphs are capable of using SatelliteCollections within their graph
+definition. Therefore, edge definitions defined between SmartCollections and
+SatelliteCollections can be created. As SatelliteCollections (and the edge
+collections between SmartGraph collections and SatelliteCollection) are globally
+replicated to each participating DB-Server, (weighted) graph traversals and
+(k-)shortest path(s) queries can partially be executed locally on each
+DB-Server. This means a larger part of the query can be executed fully local
+whenever data from the SatelliteCollections is required.
+
+Benefits of Disjoint SmartGraphs
+--------------------------------
+
Disjoint SmartGraphs are a specialized type of SmartGraphs.
In addition to the guaranteed sharding in SmartGraphs, a Disjoint SmartGraph
@@ -83,6 +95,16 @@ This ensures that graph traversals, shortest path, and k-shortest-paths queries
can be executed locally on a DB-Server, achieving improved performance for
these type of queries.
+Benefits of Hybrid Disjoint SmartGraphs
+---------------------------------------
+
+Hybrid Disjoint SmartGraphs are like Hybrid SmartGraphs but also prohibit
+edges between vertices with different `smartGraphAttribute` values. This
+restriction makes it unnecessary to replicate the edge collections between
+SmartGraph collections and SatelliteCollections to all DB-Servers for local
+execution. They are sharded like the SmartGraph collections instead
+(`distributeShardsLike`).
+
Getting started
---------------
@@ -177,3 +199,43 @@ correct sharding already).
@endDocuBlock smartGraphCreateGraphHowTo3_cluster
{% endarangoshexample %}
{% include arangoshexample.html id=examplevar script=script result=result %}
+
+**Create a Hybrid SmartGraph**
+
+In addition to the attributes you would set to create a SmartGraph, there is an
+additional attribute `satellites` you need to set. It needs to be an array of
+one or more collection names. These names can be used in edge definitions
+(relations) and these collections will be created as SatelliteCollections.
+In this example, both vertex collections are created as SatelliteCollections:
+
+{% arangoshexample examplevar="examplevar" script="script" result="result" %}
+ @startDocuBlockInline hybridSmartGraphCreateGraphHowTo1_cluster
+ @EXAMPLE_ARANGOSH_OUTPUT{hybridSmartGraphCreateGraphHowTo1_cluster}
+ var graph_module = require("@arangodb/smart-graph");
+ var rel = graph_module._relation("isCustomer", "shop", "customer")
+ var graph = graph_module._create("myGraph", [rel], [], {satellites: ["shop", "customer"], smartGraphAttribute: "region", numberOfShards: 9});
+ graph_module._graph("myGraph");
+ ~graph_module._drop("myGraph", true);
+ @END_EXAMPLE_ARANGOSH_OUTPUT
+ @endDocuBlock hybridSmartGraphCreateGraphHowTo1_cluster
+{% endarangoshexample %}
+{% include arangoshexample.html id=examplevar script=script result=result %}
+
+**Create a Hybrid Disjoint SmartGraph**
+
+The option `isDisjoint` needs to be set to `true` in addition to the other
+options for a Hybrid SmartGraph. Only the `shop` vertex collection is created
+as a SatelliteCollection in this example:
+
+{% arangoshexample examplevar="examplevar" script="script" result="result" %}
+ @startDocuBlockInline hybridSmartGraphCreateGraphHowTo2_cluster
+ @EXAMPLE_ARANGOSH_OUTPUT{hybridSmartGraphCreateGraphHowTo2_cluster}
+ var graph_module = require("@arangodb/smart-graph");
+ var rel = graph_module._relation("isCustomer", "shop", "customer")
+ var graph = graph_module._create("myGraph", [rel], [], {satellites: ["shop"], smartGraphAttribute: "region", isDisjoint: true, numberOfShards: 9});
+ graph_module._graph("myGraph");
+ ~graph_module._drop("myGraph", true);
+ @END_EXAMPLE_ARANGOSH_OUTPUT
+ @endDocuBlock hybridSmartGraphCreateGraphHowTo2_cluster
+{% endarangoshexample %}
+{% include arangoshexample.html id=examplevar script=script result=result %}
diff --git a/3.9/highlights.md b/3.9/highlights.md
index 1130f4d385..7ce6a27f9d 100644
--- a/3.9/highlights.md
+++ b/3.9/highlights.md
@@ -19,6 +19,10 @@ Version 3.9
**Enterprise Edition**
+- [**Hybrid (Disjoint) SmartGraphs**](graphs-smart-graphs.html#benefits-of-hybrid-smartgraphs):
+ SatelliteCollections can be used in (Disjoint) SmartGraphs to enable more
+ local execution of graph queries.
+
Also see [What's New in 3.9](release-notes-new-features39.html).
Version 3.8
diff --git a/3.9/release-notes-api-changes39.md b/3.9/release-notes-api-changes39.md
index 5286c881b9..9c9bd815bc 100644
--- a/3.9/release-notes-api-changes39.md
+++ b/3.9/release-notes-api-changes39.md
@@ -11,6 +11,45 @@ integrations for ArangoDB 3.9.
## HTTP RESTful API
+### Graph API (Gharial)
+
+The following changes affect the behavior of the RESTful graph APIs at
+endpoints starting with path `/_api/gharial/`:
+
+The options object now supports a new optional field `satellites` in the
+Enterprise Edition when creating a graph (POST method). If set, it needs to be
+an array of collection names. Each name must be a string and valid as collection
+name. The `satellites` option is ignored in the Community Edition.
+
+Using `satellites` during SmartGraph creation will result in a Hybrid SmartGraph.
+Using `satellites` during Disjoint SmartGraph creation will result in a Hybrid
+Disjoint SmartGraph.
+
+Hybrid (Disjoint) SmartGraphs are capable of having SatelliteCollections in their
+graph definitions. If a collection is named in `satellites` and also used in the
+graph definition itself (e.g. EdgeDefinition), this collection will be created
+as a SatelliteCollection. Hybrid (Disjoint) SmartGraphs are then capable of
+executing all types of graph queries between the regular SmartCollections and
+SatelliteCollections.
+
+The following changes affect the behavior of the RESTful graph APIs at
+endpoints starting with path `/_api/gharial/{graph}/edge` and
+`/_api/gharial/{graph}/vertex`:
+
+Added new optional `options` object that can be set when creating a new or
+modifying an existing edge definition (POST / PUT method), as well as when
+creating a new vertex collection (POST method). This was not available in
+previous ArangoDB versions. The `options` object can currently contain a field
+called `satellites` only.
+
+The `satellites` field must be an array with one or more collection name strings.
+If an EdgeDefinition contains a collection name that is also contained in the
+`satellites` option, or if the vertex collection to add is contained in the
+`satellites` option, the collection will be created as a SatelliteCollection.
+Otherwise, it will be ignored. This option only takes effect using SmartGraphs.
+
+Also see [Graph Management](http/gharial-management.html).
+
### Extended naming convention for databases
There is a new startup option `--database.extended-names-databases` to allow
diff --git a/3.9/release-notes-new-features39.md b/3.9/release-notes-new-features39.md
index 0dffb4f271..117b5d6b11 100644
--- a/3.9/release-notes-new-features39.md
+++ b/3.9/release-notes-new-features39.md
@@ -9,6 +9,38 @@ The following list shows in detail which features have been added or improved in
ArangoDB 3.9. ArangoDB 3.9 also contains several bug fixes that are not listed
here.
+Hybrid (Disjoint) SmartGraphs (Enterprise Edition)
+--------------------------------------------------
+
+SmartGraphs have been extended with a new option to create Hybrid SmartGraphs.
+Hybrid SmartGraphs are capable of using SatelliteCollections within their graph
+definition and therefore can make use of all the benefits of
+[SatelliteCollections](satellites.html).
+
+Edge definitions can now be created between SmartCollections and
+SatelliteCollections. As SatelliteCollections are globally replicated to each
+participating DB-Server, regular graph traversals, weighted traversals,
+shortest path, and k shortest paths queries can partially be executed locally on
+each DB-Server. This means that query execution can be fully local whenever
+actual data from the SatelliteCollections is being processed. This can improve
+data locality and reduce the number of network hops between cluster nodes.
+
+In case you do have collections that are needed in almost every traversal but
+are small enough to be copied over to every participating DB-Server,
+Hybrid SmartGraphs are the perfect fit, as this will increase the amount of
+local query execution.
+
+Hybrid SmartGraphs can also be disjoint. A Disjoint SmartGraph prohibits edges
+connecting different SmartGraph components. The same rule applies to
+[Hybrid Disjoint SmartGraphs](graphs-smart-graphs.html#benefits-of-hybrid-disjoint-smartgraphs).
+If your graph does not need edges between vertices with different SmartGraph
+attribute values, then you should enable this option. This topology restriction
+allows the query optimizer to improve traversal execution times, because the
+execution can be pushed down to a single DB-Server in many cases.
+
+[Hybrid SmartGraphs](graphs-smart-graphs.html#benefits-of-hybrid-smartgraphs)
+are only available in the Enterprise Edition.
+
ArangoSearch
------------