Neo4j自定义APOC存储过程实现更多炫酷的图数据库操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/superman_xxx/article/details/81514691

一、在IDEA中新建maven工程并添加以下依赖

 <properties>
        <neo4j.version>3.4.1</neo4j.version>
    </properties>

    <dependencies>
        <dependency>
            <!-- This gives us the Procedure API our runtime code uses.
                 We have a `provided` scope on it, because when this is
                 deployed in a Neo4j Instance, the API will be provided
                 by Neo4j. If you add non-Neo4j dependencies to this
                 project, their scope should normally be `compile` -->
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j</artifactId>
            <version>${neo4j.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <!-- This is used for a utility that lets us start Neo4j with
                 a specific Procedure, which is nice for writing tests. -->
            <groupId>org.neo4j.test</groupId>
            <artifactId>neo4j-harness</artifactId>
            <version>${neo4j.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <!-- Used to send cypher statements to our procedure. -->
            <groupId>org.neo4j.driver</groupId>
            <artifactId>neo4j-java-driver</artifactId>
            <version>1.4.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <!-- Neo4j Procedures require Java 8 -->
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <!-- This generates a jar-file with our procedure code,
                     plus any dependencies marked as `compile` scope.
                     This should then be deployed in the `plugins` directory
                     of each Neo4j instance in your deployment.
                     After a restart, the procedure is available for calling. -->
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

二、编写Neo4j函数/过程与测试类

Neo4j函数与过程:过程就是用 Call com.xxxx.xx (参数)来调用执行。
方法就是 可以用在 cypher中任何可以使用方法的地方如 where字句 return字句 中
如match (n) wehre com.xxx.xx(n) return n

1、编写函数(过程与函数的编写方式类似)

public class ZdrProcedures {
    /**
     * @param
     * @return
     * @Description: TODO(自定义函数 - 降序排序集合的元素)
     */
    @UserFunction(name = "zdr.apoc.sortDESC")
    public List<Object> sortDESC(@Name("coll") List<Object> coll) {
        List sorted = new ArrayList<>(coll);
        Collections.sort(sorted, new Comparator<Object>() {
            @Override
            public int compare(Object o1, Object o2) {
                Integer o1Int = Integer.valueOf(String.valueOf(o1));
                Integer o2Int = Integer.valueOf(String.valueOf(o2));
                return o2Int.compareTo(o1Int);
            }
        });
        return sorted;
    }
}

2、测试函数

public class ZdrProceduresTest {

    @Rule
    public Neo4jRule neo4j = new Neo4jRule().withFunction(ZdrProcedures.class);

    @Test
    public void sortDESC() throws Exception {
        GraphDatabaseService db = neo4j.getGraphDatabaseService();
        try (Transaction tx = db.beginTx()) {

            Map<String, Object> params = new HashMap<>();
            List<Integer> list = new ArrayList<>();
            list.add(4);
            list.add(1);
            list.add(2);
            list.add(3);
            params.put("list", list);
            Result result = db.execute("RETURN zdr.apoc.sortDESC({list}) as descList", params);
            List<Integer> descList = (List<Integer>) result.next().get("descList");
            System.out.println(descList);
        }
    }
}

3、IDEA中测试类的编写方式(方法名称右键选择go to然后点击Test即可)
这里写图片描述
4、编写过程

public class CustomerProcedures {

    /**
     * 运行环境/上下文
     */
    @Context
    public GraphDatabaseService db;

    @Context
    public Log log;

    public static Label Customer = Label.label("Customer");

    /**
     * mode - 执行模式:
     * • Mode.READ – 对图执行只读操作
     * • Mode.WRITE - 对图执行读写操作
     * • Mode.SCHEMA – 操作数据库模式,例如创建索引、限制等
     * • Mode.DBMS – 系统操作,但是不包括图操作
     * • Mode.DEFAULT – 缺省是 Mode.READ
     *
     * @param
     * @return
     * @Description: TODO(@ Description的内容会在Neo4j浏览器中调用dbms.functions () 时显示)
     */
    @Procedure(name = "zdr.apoc.createCustomer", mode = Mode.WRITE)
    @Description("customers.create(name) | Create a new Customer node")
    public Stream<NodeResult> createCustomer(@Name("name") String name) {
        List<NodeResult> output = new ArrayList<>();

        try (Transaction tx = db.beginTx()) {
            Node node = db.createNode(Customer);

            node.setProperty("name", name);

            output.add(new NodeResult(node));

            log.debug("Creating Customer with Node ID " + node.getId());

            tx.success();
        }

        return output.stream();
    }

    /**
     * @param
     * @Description: TODO(结果对象)
     * @return
     */
    public static class NodeResult {
        public Node node;

        public NodeResult(Node node) {
            this.node = node;
        }
    }
}

5、测试过程

public class CustomerProceduresTest {

    @Rule
    public Neo4jRule neo4j = new Neo4jRule()
            .withProcedure( CustomerProcedures.class );

    @Test
    public void shouldMountMyProcedures() throws Throwable {
        GraphDatabaseService db = neo4j.getGraphDatabaseService();

        try ( Transaction tx = db.beginTx() ) {
            Result res = db.execute("CALL zdr.apoc.createCustomer('Test') YIELD node RETURN node");

            Node node = (Node) res.next().get("node");

                       System.out.println(node.getId());
            System.out.println(node.getLabels());
            System.out.println(node.getRelationships());

            assertEquals(node.getProperty("name"), "Test");
        }
    }
}

三、打包安装自定义的储存过程
clean project之后install project,将JAR包复制到Neo4j安装目录下的plugins文件夹中,重启数据库即可。
这里写图片描述
这里写图片描述
Neo4j官方提供的APOC安装与自定义安装过程类似,下载JAR之后重启数据库:
这里写图片描述

return apoc.version();  // 浏览器输入命令验证APOC是否安装成功

四、在Neo4j自带浏览器测试
1、Neo4j自带的函数

RETURN apoc.coll.sort([4,2,1,3,5,8,2]) as value // 此函数是Neo4j自带的函数,默认升序排序

这里写图片描述
2、自定义函数测试

RETURN zdr.apoc.sortDESC([4,2,1,3,5,8,2]) as descList

这里写图片描述
3、自定义过程测试

CALL zdr.apoc.createCustomer('Test') YIELD node RETURN node

这里写图片描述
4、查看帮助(该过程本身就使用 dbms.procedures() 和 dbms.functions())-学会查看帮助对于快速查找过程与函数非常有用

CALL apoc.help("sort")  // 测试一
CALL apoc.help("name")  // 测试二

这里写图片描述
参考链接《APOC 用户手册 3.4.0.1》

猜你喜欢

转载自blog.csdn.net/superman_xxx/article/details/81514691