neo4j自定义call函数

在上一小节中(http://blog.wowtools.org/2019/12/27/2019-12-27-custom-neo4j1/)
,我们学习了如何同时使用嵌入模式和服务模式。本小节将学习如何扩展自定义的call函数,以满足自定义查询需求。本小节的代码基于上一小节,所以你可能要先把上一节中的示例先写出来并运行起来。

hello world

先看效果图,我们自定义了一个函数test.hello,传入一个name参数,在后台拼接字符串并返回两条测试数据。
我们执行如下查询语句后,得到对应的结果如下:
call test.hello(‘world’)
自定义函数查询效果

具体实现步骤是这样的:

编写Procedure

首先,我们新建一个Procedure类,编写自定义函数,并通过注解暴露出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.procedure.Context;
import org.neo4j.procedure.Description;
import org.neo4j.procedure.Name;
import org.neo4j.procedure.Procedure;

import java.util.stream.Stream;

/**
* 自定义call函数
* @author liuyu
* @date 2019/12/30
*/
public class TestProcedures {
@Context
public GraphDatabaseService db;


/**
* 要返回的自定义对象
*/
public static class HelloResult {
public final String name;
public final Long num;

public HelloResult(String name, Long num) {
this.name = name;
this.num = num;
}
}

@Procedure("test.hello")
@Description("hello world测试")
public Stream<HelloResult> helloWorld(@Name("name") String name) {
return Stream.of(new HelloResult(name + "-1", 123L), new HelloResult(name + "-2", 456L));
}
}

其中,HelloResult类定义了我们返回的列的类型。
方法helloWorld传入name参数,拼接了两个HelloResult对象后,以Stream封装并返回。
最后,我们通过@Procedure(“test.hello”)注解,将方法helloWorld映射到test.hello函数上。

注册Procedure

再把Procedure类注册给db就行了~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 自定义函数注册类
* @param db
* @param procedure
* @throws KernelException
*/
public static void registerProceduresAndFunctions(GraphDatabaseService db, Class<?> procedure) throws KernelException {
Procedures procedures = ((GraphDatabaseAPI) db).getDependencyResolver().resolveDependency(Procedures.class);
procedures.registerProcedure(procedure);
procedures.registerFunction(procedure);
}

//...接上一小节的代码
graphDb = neoServer.getDatabase().getGraph();
try {//将TestProcedures注册进来,所有@Procedure注解过的方法都会被注册
registerProceduresAndFunctions(graphDb, TestProcedures.class);
} catch (KernelException e) {
e.printStackTrace();
}

未完待续内容

1、HelloResult里只支持一些特定类型的属性,假如我们把num改成int型的,注册时会报异常:

1
2
3
org.neo4j.internal.kernel.api.exceptions.ProcedureException: Field `num` in record `HelloResult` cannot be converted to a Neo4j type: Don't know how to map `int` to the Neo4j Type System.
Please refer to to the documentation for full details.
For your reference, known types are: [boolean, byte[], double, java.lang.Boolean, java.lang.Double, java.lang.Long, java.lang.Number,...

如果需要自定义类型,则需要自行实现

2、如果需要查询图库并返回node对象,需要修改注解为

1
2
3
4
@Procedure(
value = "test.hello",
mode = Mode.WRITE
)

并作对应的代码修改。

这些内容将在后续章节中说明。


本文采用 CC BY-SA 4.0 协议 ,转载请注明原始链接: https://blog.wowtools.org/2019/12/27/2019-12-27-custom-neo4j2/

×

请作者喝杯咖啡