Skip to content

Commit

Permalink
docs(interactive): Add doc for creating cpp procedure with gsctl (#4231)
Browse files Browse the repository at this point in the history
As titled.
  • Loading branch information
zhanglei1949 authored Sep 18, 2024
1 parent 7567552 commit 627092e
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 4 deletions.
108 changes: 104 additions & 4 deletions docs/flex/interactive/development/stored_procedure/cpp_procedure.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,90 @@ void DeleteApp(void *app) {
### Register and Call the stored procedure
With the above `CountVertices` procedure defined, we could create a stored procedure from Interactive Python/Java SDK, or `gsctl`.
With the above `CountVertices` procedure defined, we could create a stored procedure with `gsctl` or use Interactive Python/Java SDKs.
#### gsctl
With Interactive deployed, you can register a C++ stored procedure similarly to [creating a Cypher stored procedure](../../stored_procedures.md).
##### Define the YAML
When defined, C++ stored procedures' YAML differ from Cypher procedures only in the `type` field, i.e., `cpp` versus `cypher`. Users can include the stored procedure's implementation directly in the YAML file.
```yaml
name: test_procedure
description: "Ths is a test procedure"
query: |
#include "flex/engines/graph_db/app/app_base.h"
#include "flex/engines/graph_db/database/graph_db_session.h"
#include "flex/utils/app_utils.h"
namespace gs {
// A sample app get the count of the specified vertex label, since no write
// operations are needed we inherit from ReadAppBase. Otherwise you could
// inherit from WriteAppBase.
class CountVertices : public ReadAppBase {
public:
CountVertices() {}
/**
* @brief Query function for query class.
* @param sess: GraphDBSession The interface where you can visit the graph.
* @param input: Decoder From where you could deserialize the input
* parameters.
* @param output: Encoder To where you should encode the output parameters.
*/
bool Query(const gs::GraphDBSession &sess, Decoder &input,
Encoder &output) override {
// First get the read transaction.
auto txn = sess.GetReadTransaction();
// We expect one param of type string from decoder.
if (input.empty()) {
return false;
}
std::string label_name{input.get_string()};
const auto &schema = txn.schema();
if (!schema.has_vertex_label(label_name)) {
return false; // The requested label doesn't exits.
}
auto label_id = schema.get_vertex_label_id(label_name);
// The vertices are labeled internally from 0 ~ vertex_label_num, accumulate
// the count.
output.put_int(txn.GetVertexNum(label_id));
txn.Commit();
return true;
}
};
} // namespace gs
extern "C" {
// Defines how a instance of your procedure is created.
void *CreateApp(gs::GraphDBSession &db) {
gs::CountVertices *app = new gs::CountVertices();
return static_cast<void *>(app);
}
// Defines how a instance of your procedure should be deleted.
void DeleteApp(void *app) {
gs::CountVertices *casted = static_cast<gs::CountVertices *>(app);
delete casted;
}
}
type: cpp
```

You may find the c++ code is too long, and maybe hard to update, especially if some modifications are needed. Fortunately, we support uploading the procedure implementation from file, you just need to provide the full path of the c++ file, with `@` prepended.


```yaml
name: test_procedure
description: "Ths is a test procedure"
query: "@/path/to/procedure.cc"
type: cpp
```
#### Python SDK
Expand Down Expand Up @@ -168,11 +251,26 @@ public class CreateProcedureTest{

For more tails about Java SDK Interface, please refer to [Java SDK Procedure API](../java/ProcedureManagementApi.md).

## Create a Stored Procedure

#### gsctl
First, switch to the graph where you want to create the procedure. We will use the built-in graph as an example. For instructions on creating your own graph, please refer to [Use Custom Graph](../../custom_graph_data.md).

TODO
```bash
gsctl use GRAPH gs_interactive_default_graph
```

Then create the procedure with `gsctl`:

```bash
gsctl create storedproc -f ./procedure.yaml
```

This will initiate the compilation process to convert C++ code into a dynamic library, which may take a few seconds. After compilation, it is **necessary** to restart the service to activate the stored procedures.


```bash
gsctl service restart
```

## Graph Database Engine

Expand Down Expand Up @@ -246,7 +344,6 @@ public class CreateProcedureTest{


```python
import os
from gs_interactive.client.driver import Driver
from gs_interactive.models import *
from gs_interactive.client.utils import *
Expand All @@ -260,6 +357,9 @@ encoder.put_string("person") # input label name
encoder.put_byte(1) # procedure id 1
resp = sess.call_procedure_raw(graph_id="1", params=encoder.get_bytes())
assert resp.is_ok()
decoder = Decoder(resp.value)
num = decoder.get_int()
print(f"vertices num: {num}")
```

## Programming Interface
Expand Down
2 changes: 2 additions & 0 deletions docs/flex/interactive/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ unzip cypher-shell-4.4.19.zip && cd cypher-shell
@neo4j> MATCH (n) RETURN n LIMIT 10;
```

You could also make use of Interactive SDKs,[Java SDK](./development/java/java_sdk.md) or [Python SDK](./development/python/, to connect to the Interactive service using the python_sdk.md) to submit queries.

## Close the connection

If you want to disconnect to coordinator, just type
Expand Down
4 changes: 4 additions & 0 deletions docs/flex/interactive/stored_procedures.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,7 @@ You can also call the stored procedure via neo4j-native tools, like `cypher-shel
```cypher
CALL test_procedure("marko") YIELD *;
```



In addition to defining a stored procedure with a Cypher query, we also support for customizing query execution through C++ stored procedures. See [C++ Stored Procedure](./development/stored_procedure/cpp_procedure.md).

0 comments on commit 627092e

Please sign in to comment.