Java SDK 参考文档

Interactive Java SDK参考手册是为开发者提供的全面指南,旨在帮助他们将Interactive服务集成到Java应用程序中。该SDK使用户能够无缝连接到Interactive,并利用其强大的图管理、存储过程管理和查询执行功能。

系统要求

构建API客户端库需要:

  1. Java 1.8及以上版本

  2. Maven (3.8.3+)/Gradle (7.2+)

安装

要将API客户端库安装到本地Maven仓库,只需执行:

git clone https://github.com/alibaba/GraphScope.git
cd GraphScope/flex/interactive/sdk/java
mvn clean install

要将其部署到远程Maven仓库,请配置仓库设置并执行:

mvn clean deploy

更多信息请参考OSSRH指南

Maven用户

将此依赖项添加到项目的POM中:

<dependency>
  <groupId>com.alibaba.graphscope</groupId>
  <artifactId>interactive-sdk</artifactId>
  <version>0.3</version>
</dependency>

其他

首先通过执行以下命令生成JAR包:

mvn clean package

然后手动安装以下JAR包:

  • target/interactive-sdk-0.3.jar

  • target/lib/*.jar

快速开始

首先,通过Interactive Getting Started安装并启动交互式服务,您将获得该服务的所有端点。

You can connect to Interactive service with Interactive SDK, with following environment variables declared.

############################################################################################
    export INTERACTIVE_ADMIN_ENDPOINT=http://127.0.0.1:7777
    export INTERACTIVE_STORED_PROC_ENDPOINT=http://127.0.0.1:10000
    export INTERACTIVE_CYPHER_ENDPOINT=neo4j://127.0.0.1:7687
############################################################################################

注意

如果在部署Interactive时自定义了端口,请记得将默认端口替换为您自定义的端口。

请记得导出这些环境变量。

连接并提交查询

交互式界面为您提供了一个默认图modern_graph。您可以连接到交互式端点,并尝试运行以下代码来执行简单查询。

package com.alibaba.graphscope;

import com.alibaba.graphscope.interactive.client.Driver;
import com.alibaba.graphscope.interactive.client.Session;
import com.alibaba.graphscope.interactive.models.*;

public class GettingStarted {
    public static void main(String[] args) {
        Driver driver = Driver.connect();
        Session session = driver.session();

        // start a query
        // run cypher query
        try (org.neo4j.driver.Session neo4jSession = driver.getNeo4jSession()) {
            org.neo4j.driver.Result result = neo4jSession.run("MATCH(a) return COUNT(a);");
            System.out.println("result: " + result.toString());
        }
        return;
    }
}

创建新图

要创建新图,用户需要指定名称、描述、顶点类型和边类型。 有关图的详细数据模型,请参阅数据模型

在本示例中,我们将创建一个仅包含一种顶点类型persson和一种名为knows的边类型的简单图。

public class GettingStarted {
    private static final String TEST_GRAPH_SCHEMA_JSON = "{\n" +
            "    \"name\": \"test_graph\",\n" +
            "    \"description\": \"This is a test graph\",\n" +
            "    \"schema\": {\n" +
            "        \"vertex_types\": [\n" +
            "            {\n" +
            "                \"type_name\": \"person\",\n" +
            "                \"properties\": [\n" +
            "                    {\n" +
            "                        \"property_name\": \"id\",\n" +
            "                        \"property_type\": {\"primitive_type\": \"DT_SIGNED_INT64\"},\n" +
            "                    },\n" +
            "                    {\n" +
            "                        \"property_name\": \"name\",\n" +
            "                        \"property_type\": {\"string\": {\"long_text\": \"\"}},\n" +
            "                    },\n" +
            "                    {\n" +
            "                        \"property_name\": \"age\",\n" +
            "                        \"property_type\": {\"primitive_type\": \"DT_SIGNED_INT32\"},\n" +
            "                    },\n" +
            "                ],\n" +
            "                \"primary_keys\": [\"id\"],\n" +
            "            }\n" +
            "        ],\n" +
            "        \"edge_types\": [\n" +
            "            {\n" +
            "                \"type_name\": \"knows\",\n" +
            "                \"vertex_type_pair_relations\": [\n" +
            "                    {\n" +
            "                        \"source_vertex\": \"person\",\n" +
            "                        \"destination_vertex\": \"person\",\n" +
            "                        \"relation\": \"MANY_TO_MANY\",\n" +
            "                    }\n" +
            "                ],\n" +
            "                \"properties\": [\n" +
            "                    {\n" +
            "                        \"property_name\": \"weight\",\n" +
            "                        \"property_type\": {\"primitive_type\": \"DT_DOUBLE\"},\n" +
            "                    }\n" +
            "                ],\n" +
            "                \"primary_keys\": [],\n" +
            "            }\n" +
            "        ],\n" +
            "    },\n" +
            "}";

    public static String createGraph(Session session) throws IOException {
        CreateGraphRequest graph = CreateGraphRequest.fromJson(TEST_GRAPH_SCHEMA_JSON);
        Result<CreateGraphResponse> rep = session.createGraph(graph);
        if (rep.isOk()) {
            System.out.println("create graph success");
        } else {
            throw new RuntimeException("create graph failed: " + rep.getStatusMessage());
        }
        String graphId = rep.getValue().getGraphId();
        System.out.println("graphId: " + graphId);
        return graphId;
    }

    public static void main(String[] args) {
        //Previous code...
        Session session = driver.session();
        String graphId = createGraph(sess);
        return ;
    }
}

在上述示例中,通过JSON字符串定义了一个名为test_graph的图。您也可以使用CreateGraphRequest提供的编程接口来定义图。当您调用createGraph方法时,会返回一个表示该图唯一标识符的字符串。

将数据导入图

创建新图后,您可能需要将数据导入到新创建的图中。 有关数据导入的详细配置,请参阅数据导入配置

例如,您可以将本地CSV文件导入test_graph。请注意,目前仅支持CSV格式文件。请记得将/path/to/person.csv/path/to/person_knows_person.csv替换为实际的本地路径。您可以从GraphScope Interactive Github仓库下载这些文件。

public class GettingStarted {
    //Remember to replace the path with your own file path
    private static final String TEST_GRAPH_BULK_LOADING_JSON = "{\n" +
            "    \"vertex_mappings\": [\n" +
            "        {\n" +
            "            \"type_name\": \"person\",\n" +
            "            \"inputs\": [\"@/path/to/person.csv\"],\n" +
            "            \"column_mappings\": [\n" +
            "                {\"column\": {\"index\": 0, \"name\": \"id\"}, \"property\": \"id\"},\n" +
            "                {\"column\": {\"index\": 1, \"name\": \"name\"}, \"property\": \"name\"},\n" +
            "                {\"column\": {\"index\": 2, \"name\": \"age\"}, \"property\": \"age\"},\n" +
            "            ],\n" +
            "        }\n" +
            "    ],\n" +
            "    \"edge_mappings\": [\n" +
            "        {\n" +
            "            \"type_triplet\": {\n" +
            "                \"edge\": \"knows\",\n" +
            "                \"source_vertex\": \"person\",\n" +
            "                \"destination_vertex\": \"person\",\n" +
            "            },\n" +
            "            \"inputs\": [\n" +
            "                \"@/path/to/person_knows_person.csv\"\n" +
            "            ],\n" +
            "            \"source_vertex_mappings\": [\n" +
            "                {\"column\": {\"index\": 0, \"name\": \"person.id\"}, \"property\": \"id\"}\n" +
            "            ],\n" +
            "            \"destination_vertex_mappings\": [\n" +
            "                {\"column\": {\"index\": 1, \"name\": \"person.id\"}, \"property\": \"id\"}\n" +
            "            ],\n" +
            "            \"column_mappings\": [\n" +
            "                {\"column\": {\"index\": 2, \"name\": \"weight\"}, \"property\": \"weight\"}\n" +
            "            ],\n" +
            "        }\n" +
            "    ],\n" +
            "}";

    public static void bulkLoading(Session session, String graphId) throws IOException {
        SchemaMapping schemaMapping = SchemaMapping.fromJson(TEST_GRAPH_BULK_LOADING_JSON);
        Result<JobResponse> rep = session.bulkLoading(graphId, schemaMapping);
        if (rep.isOk()) {
            System.out.println("Bulk loading success");
        } else {
            throw new RuntimeException("bulk loading failed: " + rep.getStatusMessage());
        }
        String jobId = rep.getValue().getJobId();
        System.out.println("job id: " + jobId);
        // Wait job finish
        while (true) {
            Result<JobStatus> rep = session.getJobStatus(jobId);
            if (!rep.isOk()) {
                throw new RuntimeException("get job status failed: " + rep.getStatusMessage());
            }
            JobStatus job = rep.getValue();
            if (job.getStatus() == JobStatus.StatusEnum.SUCCESS) {
                System.out.println("job finished");
                break;
            } else if (job.getStatus() == JobStatus.StatusEnum.FAILED) {
                throw new RuntimeException("job failed");
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        //Previous code...
        Session session = driver.session();
        String graphId = createGraph(sess);
        bulkLoading(sess, graphId);
        return ;
    }
}

对于每个顶点/边类型,您需要提供输入数据源和列映射信息。 请记住在本地文件路径的开头添加@Session.bulkLoading()会向服务提交一个数据加载作业,我们可以通过Session.getJobStatus()查询作业状态,并等待作业成功完成。

创建存储过程

存储过程可以注册到GraphScope Interactive中以封装和复用复杂的图操作。Interactive同时支持cypherc++查询作为存储过程。 通过以下代码,您将创建一个名为testProcedure的过程,该过程通过cypher查询定义。

public class GettingStarted{
    public static String createProcedure(Session sess, String graphId) {
        String procName = "testProcedure";
        CreateProcedureRequest procedure =
                new CreateProcedureRequest()
                        .name(procName)
                        .description("a simple test procedure")
                        .query("MATCH(p:person) RETURN COUNT(p);")
                        .type(CreateProcedureRequest.TypeEnum.CYPHER);
        Result<CreateProcedureResponse> resp = session.createProcedure(graphId, procedure);
        if (resp.isOk()) {
            System.out.println("create procedure success");
        } else {
            throw new RuntimeException("create procedure failed: " + resp.getStatusMessage());
        }
        return procName;
    }

    public static void main(String[] args) {
        //Previous code...
        Session session = driver.session();
        String graphId = createGraph(sess);
        bulkLoading(sess, graphId);
        String procName = createProcedure(sess, graphId);
        return ;
    }
}

当前无法调用该过程,因为交互式服务尚未切换到新创建的test_graph。我们需要在test_graph上启动服务。

在新图上启动查询服务

虽然Interactive在逻辑和存储层面支持多图操作,但它一次只能服务于一个图。这意味着在任何时刻,只有一张图可提供查询服务。因此我们需要通过以下代码切换到新创建的test_graph

public class GettingStarted{
    public static void startService(Session sess, String graphId){
        Result<String> startServiceResponse =
            session.startService(new StartServiceRequest().graphId(graphId));
        if (startServiceResponse.isOk()) {
            System.out.println("start service success");
        } else {
            throw new RuntimeException(
                    "start service failed: " + startServiceResponse.getStatusMessage());
        }
    }

    public static void main(String[] args) {
        //Previous code...
        Session session = driver.session();
        String graphId = createGraph(sess);
        bulkLoading(sess, graphId);
        String procName = createProcedure(sess, graphId);
        starService(sess, graphId);
        return ;
    }
}

向新图提交查询

在新图上启动查询服务后,我们现在可以向test_graph提交查询请求。

提交Cypher查询

public class GettingStarted{
    public static void main(String[] args) {
        // Previous code...
        // run cypher query
        try (org.neo4j.driver.Session neo4jSession = driver.getNeo4jSession()) {
            org.neo4j.driver.Result result = neo4jSession.run("MATCH(a) return COUNT(a);");
            System.out.println("result: " + result.toString());
        }
        return ;
    }
}

查询存储过程

public class GettingStarted{
    public static void main(String[] args) {
        // Previous code...
        // call the stored procedure
        try (org.neo4j.driver.Session neo4jSession = driver.getNeo4jSession()) {
            org.neo4j.driver.Result result = neo4jSession.run("CALL testProcedure() YIELD *;");
            System.out.println("result: " + result.toString());
        }
        return ;
    }
}

删除图

最后,我们可以删除该图。与该图关联的图数据和存储过程也将被删除。

public class GettingStarted{
    public static void main(String[] args) {
        // Previous code...
        Result<String> deleteGraphResponse = session.deleteGraph(graphId);
        if (deleteGraphResponse.isOk()) {
            System.out.println("delete graph success");
        } else {
            throw new RuntimeException("delete graph failed: " + deleteGraphResponse.getStatusMessage());
        }
        return ;
    }
}

完整示例请参考 Java SDK Example

服务API文档

交互式SDK中的API分为五大类。

  • 图管理API

  • ProcedureManagementApi

  • 作业管理API

  • 服务管理API

  • 查询服务API

  • 顶点API

  • EdgeApi

所有URI均相对于${INTERACTIVE_ADMIN_ENDPOINT}

方法

HTTP请求

描述

GraphManagementApi

批量加载

POST /v1/graph/{graph_id}/dataloading

GraphManagementApi

CreateGraph

POST /v1/graph

GraphManagementApi

DeleteGraph

DELETE /v1/graph/{graph_id}

GraphManagementApi

GetGraphMeta

GET /v1/graph/{graph_id}

GraphManagementApi

GetGraphSchema

GET /v1/graph/{graph_id}/schema

GraphManagementApi

ListGraphs

GET /v1/graph

JobManagementApi

CancelJob

DELETE /v1/job/{job_id}

JobManagementApi

GetJobById

GET /v1/job/{job_id}

JobManagementApi

ListJobs

GET /v1/job

ProcedureManagementApi

CreateProcedure

POST /v1/graph/{graph_id}/procedure

ProcedureManagementApi

DeleteProcedure

DELETE /v1/graph/{graph_id}/procedure/{procedure_id}

ProcedureManagementApi

GetProcedure

GET /v1/graph/{graph_id}/procedure/{procedure_id}

ProcedureManagementApi

ListProcedures

GET /v1/graph/{graph_id}/procedure

ProcedureManagementApi

UpdateProcedure

PUT /v1/graph/{graph_id}/procedure/{procedure_id}

ServiceManagementApi

GetServiceStatus

GET /v1/service/status

ServiceManagementApi

RestartService

POST /v1/service/restart

ServiceManagementApi

StartService

POST /v1/service/start

ServiceManagementApi

StopService

POST /v1/service/stop

QueryServiceApi

CallProcedure

POST /v1/graph/{graph_id}/query

QueryServiceApi

CallProcedureOnCurrentGraph

POST /v1/graph/current/query

VertexApi

addVertex

POST /v1/graph/{graph_id}/vertex

向图中添加顶点

VertexApi

getVertex

GET /v1/graph/{graph_id}/vertex

通过顶点主键获取顶点属性。

VertexApi

updateVertex

PUT /v1/graph/{graph_id}/vertex

更新顶点属性

EdgeApi

addEdge

POST /v1/graph/{graph_id}/edge

向图中添加边

EdgeApi

getEdge

GET /v1/graph/{graph_id}/edge

通过源顶点和目标顶点的主键获取边的属性。

EdgeApi

updateEdge

PUT /v1/graph/{graph_id}/edge

更新边的属性

注意

Interactive目前不支持删除顶点/边。

工具API文档

除了服务API的文档外,我们还提供Utility APIs的文档。

数据结构文档

授权文档

目前暂不支持身份验证功能,我们将在近期引入与授权相关的实现。