简体   繁体   English

Neo4j 3.0.3在Scala中的存储过程

[英]Neo4j 3.0.3 Stored procedures in Scala

Is there any sample Scala code available for creating stored procedures in Neo4j-3.0.3 ? 是否有任何示例Scala代码可用于在Neo4j-3.0.3中创建存储过程?

I have been trying to create one simple Scala based stored procedure. 我一直在尝试创建一个基于Scala的简单存储过程。 Below is the Error message I get when I copy my scala-jar file to the neo4j-plugins directory and start the neo4j server : 以下是将scala-jar文件复制到neo4j-plugins目录并启动neo4j服务器时收到的错误消息:

=================
Caused by: org.neo4j.kernel.lifecycle.LifecycleException: Component 'org.neo4j.kernel.impl.proc.Procedures@1ac0223' was successfully initialized, but failed to start. Please see attached cause exception.
        at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.start(LifeSupport.java:444)
        at org.neo4j.kernel.lifecycle.LifeSupport.start(LifeSupport.java:107)
        at org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.newFacade(GraphDatabaseFacadeFactory.java:140)
        ... 10 more
Caused by: org.neo4j.kernel.api.exceptions.ProcedureException: Unable to find a usable public no-argument constructor in the class `neoscala`. Please add a valid, public constructor, recompile the class and try again.
=================

The scala class that I have used is : 我使用的scala类是:

package neoproc

    import org.neo4j.graphdb.GraphDatabaseService
    import org.neo4j.procedure.Procedure;
    import javax.ws.rs.core.{Context, Response}

    class neoscala(@Context db: GraphDatabaseService) {

     @Procedure
    def alice():String = {
        String.valueOf(db.execute( "MATCH (n:User) return n" ));
     }
    }

Your Scala class declares a constructor with a GraphDatabaseService argument, and the exception tells you that it only wants a no-argument constructor. 您的Scala类使用GraphDatabaseService参数声明一个构造函数,该异常告诉您它只需要一个无参数的构造函数。

It's documented in both 两者都有记录

  • the user documentation : 用户文档

    Only static fields and @Context-annotated fields are allowed in Procedure classes. 过程类中仅允许使用静态字段和@Context注释的字段。

  • the Javadoc : Javadoc

    The procedure method itself can contain arbitrary Java code - but in order to work with the underlying graph, it must have access to the graph API. 过程方法本身可以包含任意Java代码-但是要使用基础图,它必须有权访问图API。 This is done by declaring fields in the procedure class, and annotating them with the Context annotation. 这是通过在过程类中声明字段并使用Context注释对其进行注释来完成的。 Fields declared this way are automatically injected with the requested resource. 以此方式声明的字段将自动注入请求的资源。 This is how procedures gain access to APIs to do work with. 这就是过程如何访问要使用的API的方式。

    All fields in the class containing the procedure declaration must either be static; 包含过程声明的类中的所有字段都必须是静态的。 or it must be public, non-final and annotated with Context. 或者它必须是公开的,非最终的并且带有上下文注释。

Apparently it's not possible to create a class with a public field in Scala , so you'll have to create a parent Java class with the public field, and extend it with your Scala class: 显然,不可能在Scala中创建具有公共字段的类 ,因此您必须使用公共字段创建父Java类,并使用Scala类对其进行扩展:

// ProcedureAdapter.java
public abstract class ScalaProcedureAdapter {
    @Context
    public GraphDatabaseService db;
}

// neoscala.scala
class neoscala extends ScalaProcedureAdapter {
    // ...
}

Here is the solution for this : 这是解决方案:

We will create Class in scala : 我们将在scala中创建Class:

  class FullTextIndex extends JavaHelper {
     @Procedure("example.search")
     @PerformsWrites
         def search(@Name("label") label: String,
                    @Name("query") query:  String): Stream[SearchHit] = {
           //declare your method 
           }

        val nodes: Stream[Node] = db.index.forNodes(index).query(query).stream

       val newFunction: java.util.function.Function[Node, SearchHit] = (node: Node) => new SearchHit(node)
           nodes.map {
                 newFunction
           }
      }

       private def indexName(label: String): String = {
           "label-" + label
   }
 }

Procedure in Neo4j always return result in Stream and it is a latest feature in Java8 so we will also used Java Class for return the final result and For defining the public variable. Neo4j中的过程总是在Stream中返回结果,它是Java8中的最新功能,因此我们还将使用Java类来返回最终结果并用于定义公共变量。

We will create Java class for result : 我们将为结果创建Java类:

public class JavaHelper {

@Context
public GraphDatabaseService db;

@Context
public Log log;

 public static class SearchHit {
    //your result code here
}

You can refer knoldus blog for Neo4j User Defined Procedure for creating and storing Neo4j Procedure with Scala. 您可以参考knoldus博客以获取Neo4j用户定义的过程 ,以使用Scala创建和存储Neo4j过程。 Here you will also find sample code with git hub repository. 在这里,您还将找到带有git hub存储库的示例代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM