使用java编写自定义函数 拓展Neo4j功能
neo4j提供了丰富而强大的函数,可通过CALL dbms.procedures()查询 在一些复杂的应用场景中,neo4j自带的各种函数不能满足需求的时候,我们可以通过自定义函数去扩展和提升Neo4j的一些常用命令功能。 自定义函数的结果输出类型具体包括以下类型: • 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, Object> • List
代码实现: jar包依赖:
<properties>
<neo4j.version>3.4.9</neo4j.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>${neo4j.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.neo4j.test</groupId>
<artifactId>neo4j-harness</artifactId>
<version>${neo4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<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>
</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>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
</plugin>
</plugins>
</build>
自定义函数:
package com.zhbr.neo4j;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.procedure.Description;
import org.neo4j.procedure.Name;
import org.neo4j.procedure.UserFunction;
import java.util.*;
public class UserFunctions {
@UserFunction("my.hello")
@Description("问候")
public String hello(@Name("name") String name) {
return "Hello "+name;
}
@UserFunction("my.add")
@Description("加法")
public double add(@Name("i") double i,@Name("y") double y) {
return i+y;
}
@UserFunction("my.compare")
@Description("比较两个节点的属性是否相同")
public Boolean compare(@Name("node1") Node i, @Name("node2") Node y) {
String i_ywxtmc = (String) i.getProperty("ywxtmc");
String y_ywxtmc = (String) y.getProperty("ywxtmc");
if (i_ywxtmc.equals(y_ywxtmc)){
return true;
}
return false;
}
@UserFunction("my.recommendation")
@Description("写的乱七八糟的推荐算法")
public String recommendation(@Name("node") Node node){
ArrayList<Integer> maxCount = new ArrayList<>();
ArrayList<String> moviesBox = new ArrayList<>();
Iterable<Relationship> relationships = node.getRelationships();
for (Relationship relationship : relationships){
Node nodes = relationship.getEndNode();
String likeMovies = (String) nodes.getProperty("name");
moviesBox.add(likeMovies);
}
Map<String, Integer> listElements = frequencyOfListElements(moviesBox);
for (Map.Entry<String, Integer> entry : listElements.entrySet()){
int value = entry.getValue().intValue();
maxCount.add(value);
}
Integer max = Collections.max(maxCount);
String key = getKey(listElements, max);
return key;
}
/**
* java统计List集合中每个元素出现的次数
* 例如frequencyOfListElements(["111","111","222"])
* ->
* 则返回Map {"111"=2,"222"=1}
* @param items
* @return Map<String,Integer>
* @author wuqx
*/
public Map<String,Integer> frequencyOfListElements(List<String> items ) {
if (items == null || items.size() == 0) return null;
Map<String, Integer> map = new HashMap<String, Integer>();
for (String temp : items) {
Integer count = map.get(temp);
map.put(temp, (count == null) ? 1 : count + 1);
}
return map;
}
/**
* 根据value找key
* @param map
* @param value
* @return
*/
private String getKey(Map<String, Integer> map, Object value) {
String key = "";
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (value.equals(entry.getValue())) {
key = entry.getKey();
continue;
}
}
return key;
}
}
代码测试:
package com.zhbr.neo4j;
import org.junit.Rule;
import org.junit.Test;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Result;
import org.neo4j.harness.junit.Neo4jRule;
public class UserFunctionTest {
@Rule
public Neo4jRule neo4j = new Neo4jRule().withFunction(UserFunctions.class);
@Test
public void testGreeting() {
GraphDatabaseService db = neo4j.getGraphDatabaseService();
Result result = db.execute("return my.hello('world') as res");
System.out.println(result.next().get("res").toString());
Result result1 = db.execute("return my.add(1,2) as res");
System.out.println(result1.next().get("res").toString());
}
}
将jar包添加到neo4j maven package后会在target目录下生成jar包,将jar包放到neo4j项目的plugin目录下,重启neo4j即可
测试
本文参考: https://blog.csdn.net/yuanyk1222/article/details/94558980