用户定义的聚合函数
用户定义的聚合函数是聚合数据并返回单个结果的函数。有关用户定义的存储过程、函数和聚合函数之间的比较,请参见Neo4j 定制代码。
调用聚合函数
用户定义的聚合函数与其他任何 Cypher 聚合函数调用方式相同。函数名称必须完全限定,因此定义在 org.neo4j.examples
包中的名为 longestString
的函数可以使用以下方式调用:
MATCH (p: Person) WHERE p.age = 36
RETURN org.neo4j.examples.longestString(p.name)
编写用户定义的聚合函数
用户定义的聚合函数使用 @UserAggregationFunction
进行注解。被注解的函数必须返回一个聚合器类的实例。聚合器类包含一个使用 @UserAggregationUpdate
注解的方法和一个使用 @UserAggregationResult
注解的方法。使用 @UserAggregationUpdate
注解的方法将被多次调用,并使类能够聚合数据。当聚合完成后,使用 @UserAggregationResult
注解的方法将被调用一次,并返回聚合结果。
有关值和类型的详细信息,请参见值和类型。
有关更多详细信息,请参见 Neo4j Javadoc 中关于 org.neo4j.procedure.UserAggregationFunction
的内容。
从聚合函数内部发出错误的正确方法是抛出 |
package example;
import org.neo4j.procedure.Description;
import org.neo4j.procedure.Name;
import org.neo4j.procedure.UserAggregationFunction;
import org.neo4j.procedure.UserAggregationResult;
import org.neo4j.procedure.UserAggregationUpdate;
public class LongestString
{
@UserAggregationFunction
@Description( "org.neo4j.function.example.longestString(string) - aggregates the longest string found" )
public LongStringAggregator longestString()
{
return new LongStringAggregator();
}
public static class LongStringAggregator
{
private int longest;
private String longestString;
@UserAggregationUpdate
public void findLongest(
@Name( "string" ) String string )
{
if ( string != null && string.length() > longest)
{
longest = string.length();
longestString = string;
}
}
@UserAggregationResult
public String result()
{
return longestString;
}
}
}
集成测试
用户定义的聚合函数的测试创建方式与普通用户定义的函数的测试创建方式相同。
一个用于测试查找最长字符串的用户定义的聚合函数的模板。
package example;
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 LongestStringTest
{
// This rule starts a Neo4j instance
@Rule
public Neo4jRule neo4j = new Neo4jRule()
// This is the function to test
.withAggregationFunction( LongestString.class );
@Test
public void shouldAllowIndexingAndFindingANode() throws Throwable
{
// This is in a try-block, to make sure you close the driver after the test
try( Driver driver = GraphDatabase.driver( neo4j.boltURI() , Config.build().withEncryptionLevel( Config.EncryptionLevel.NONE ).toConfig() ) )
{
// Given
Session session = driver.session();
// When
String result = session.run( "UNWIND ["abc", "abcd", "ab"] AS string RETURN example.longestString(string) AS result").single().get("result").asString();
// Then
assertThat( result, equalTo( "abcd" ) );
}
}
}