一、背景介紹
用戶自定義函數,顧名思義就是開發一些個性化方法去解決複雜的業務邏輯問題。雖然它的功能還不夠強大,但是足夠去擴展和提升Neo4j的一些常用命令功能。
在Neo4j中,自定義函數是需求利用Java語言去獨立開發,然後生成.jar文件去部署在圖數據庫的安裝目錄plugin中,如果是集群的話,每臺服務器都需要部署。再重新啟動圖數據庫才能生效。
對於自定義函數的調用,它跟常用的Cypher方法一樣,只是函數名的規範會有限定,比如自定義函數join,它在Java工程中的目錄結構為org.neo4j.examples,因此它在調用時的規範寫法為org.neo4j.examples.join(參數)。
另外,自定義函數的結果輸出類型很多,具體如下所示:
• java.lang.Boolean or boolean
• java.lang.Double or double
• java.lang.Long or long
• java.lang.Number
• java.lang.Object
• java.lang.String or string
• java.util.List
• java.util.Map
• org.neo4j.graphdb.Node
• org.neo4j.graphdb.Relationship
• org.neo4j.graphdb.Path
• org.neo4j.graphdb.spatial.Geometry
• org.neo4j.graphdb.spatial.Point
• Map<string>
• List
當然,現有的Neo4j圖數據庫也包含了很多自定義的函數,你可以在正式實踐之前去初步瞭解一下,在命令框輸入:CALL dbms.procedures()即可查詢到,結果輸出包含了函數名、用法說明和功能描述。你後期的開發也可以按照這樣的規範標準來。
二、基礎準備
在瞭解完背景介紹之後,除了部署好Java和Neo4j的環境之外,你最好去按照好Maven軟件,並配置到IDE中,因為它可以極大簡化你開發的工作量。
其中,對於Maven的安裝,請自行百度。不過這裡提示一點,Java的版本需要為1.8,IDE可以選擇最新的STS,Maven可以選擇3.3.9版本。而對於IDE中Maven的配置,也請自行百度。
在安裝部署結束,你可以通過CMD命令窗口輸入:mvn -version去確認是否成功。
一切完成之後,現在就正式在IDE中去創建Maven工程,其中Group Id填寫cn.lpwanger(你也可以更換),Artifact Id填寫neo4jFuns,點擊Finish即可。
接下來,我們還需要在Maven工程的pom.xml文件引入一些依賴包,分別如下:
<dependency>
<groupid>org.neo4j.driver/<groupid>
<artifactid>neo4j-java-driver/<artifactid>
<version>1.4.0/<version>
<dependency>
<groupid>org.neo4j/<groupid>
<artifactid>neo4j/<artifactid>
<version>3.4.9/<version>
<dependency>
<groupid>org.neo4j.test/<groupid>
<artifactid>neo4j-harness/<artifactid>
<version>3.4.9/<version>
<scope>test/<scope>
你也可以直接通過Maven中央倉庫去搜索。如果有些公司不能從外網下載的話,你可以在pom.xml配置私庫地址,從公司的私庫中去下載。
一切完成之後,我們就可以正式實踐去開發屬於自己的第一個自定義函數了。
三、實踐開發
這裡給出一個官方的參考例子,原理都很好理解。
我們先在src/main/java目錄下的cn.lpwanger.neo4jFuns創建一個類,命名為Join,具體代碼如下:
import org.neo4j.procedure.Name;
import org.neo4j.procedure.Procedure;
import org.neo4j.procedure.UserFunction;
public class Join
{
@UserFunction
@Description("cn.lpwanger.neo4jFuns.join(['s1','s2',...], delimiter) - join the given strings with the given delimiter.")
public String join(
@Name("strings") List<string> strings,/<string>
@Name(value = "delimiter", defaultValue = ",") String delimiter) {
if (strings == null || delimiter == null) {
return null;
}
return String.join(delimiter, strings);
}
}
註釋理解:
@UserFunction,它缺失的函數名是package-name.functionName,例如cn.lpwanger.neo4jFuns.join,當然也可以通過name參數去修改函數名,如@UserFunction( name = "package.function" )。
@Description是函數的功能描述說明,它的內容會在Neo4j瀏覽器中調用dbms.functions() 時顯示。。
@Name("strings") List<string> strings是函數的參數說明。/<string>
@Procedure( name = "customers.create", mode = Mode.WRITE ),它屬於用戶自定義的過程,mode的值代表執行模式,更多的含義如下所屬:
• Mode.READ – 對圖執行只讀操作
• Mode.WRITE - 對圖執行讀寫操作
• Mode.SCHEMA – 操作數據庫模式,例如創建索引、限制等
• Mode.DBMS – 系統操作,但是不包括圖操作
• Mode.DEFAULT – 缺省是 Mode.READ
該函數的目的在於通過指定的分隔符去拼接列表中的所有字符串元素,就比如['a','b']最終返回'a,b'值。
完成這一步之後,在正式生成.jar文件之前,建議大家都去做一個單元測試,這是一個良好的開發習慣。
因此,我們繼續在src/test/java目錄下的cn.lpwanger.neo4jFuns創建一個測試類:JoinTest,具體代碼如下:
import org.junit.Rule;
import org.junit.Test;
import org.neo4j.driver.v1.*;
import org.neo4j.harness.junit.Neo4jRule;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
public class JoinTest
{
@Rule
public Neo4jRule neo4j = new Neo4jRule()
.withFunction( Join.class );
@Test public void shouldAllowIndexingAndFindingANode() throws Throwable { try( Driver driver = GraphDatabase.driver( neo4j.boltURI() , Config.build().withEncryptionLevel( Config.EncryptionLevel.NONE ).toConfig() ) ) { Session session = driver.session(); String result = session.run( "RETURN example.join(['Hello', 'World']) AS result").single().get("result").asString(); assertThat( result, equalTo( "Hello,World" ) ); } }
}
最後右鍵JoinTest.java類,通過Run As點擊JUnit Test去運行,如果assertThat結果輸出為True就測試通過。
最後,你就可以生成neo4jFuns.jar包,放置於neo4j的plugins目錄下,重新啟動neo4j服務即可生效,執行下面的命令可以驗證:
WITH ['a','b'] as value RETURN cn.lpwanger.neo4jFuns.join(value);
結果輸出:"a,b",那就說明添加成功。
以後你也可以結合實際的業務需求去開發更多的自定義函數,提高Cypher語言處理圖數據庫的便捷性。
四、參考文獻
[1] 6.2. User-defined functions - Chapter 6. Extending Neo4j
[2] 6.1. Procedures - Chapter 6. Extending Neo4j
[3] User Defined Procedures and Functions - Neo4j Grap...
閱讀更多 科多大 的文章