Sparql自定义propertyFunction

Property function编写有两种方法,对应着不同的注册方式。第一种是实现PropertyFunctionFactory 接口,第二种是直接继承PFuncSimple。

继承propertyFunction

继承PropertyFunctionFactory接口的方法需要override create(final String url)函数。该函数返回一个PropertyFunction类,在里面我们可以return new PFuncSimple(){//dosth.}的一个匿名类,重载相关函数。(其实重写里面的和直接继承PFuncSimple也没啥区别了)

具体框架如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MyFunc1 implements PropertyFunctionFactory{
@Override
public PropertyFunction create(final String uri)
{
return new PFuncSimple()
{
@Override
public QueryIterator execEvaluated(final Binding parent, final Node subject, final Node predicate, final Node object, final ExecutionContext execCxt)
{
Graph graph = execCxt.getActiveGraph() ;
//dosth ...
return sth.;
}
};
}
}

注册该函数的方法有两种,注册到全局和注册到具体的dataset。另外也可以通过java:这个fake URI动态注册

1
2
3
4
5
6
7
8
9
10
//全局
final PropertyFunctionRegistry reg = PropertyFunctionRegistry.chooseRegistry(ARQ.getContext());
reg.put("urn:ex:fn#example", new ExamplePropertyFunctionFactory);
PropertyFunctionRegistry.set(ARQ.getContext(), reg);
//dataset
final Dataset ds = DatasetFactory.createMem();
final PropertyFunctionRegistry reg = PropertyFunctionRegistry.chooseRegistry(ds.getContext());
reg.put("urn:ex:fn#example", new ExamplePropertyFunctionFactory);
PropertyFunctionRegistry.set(ds.getContext(), reg);

这种方法是官方文档中给出的

继承PFuncSimple

第二种方法是继承PFuncSimple。继承以后重写build函数和execEvaluated函数。

  • build:Called during query plan construction immediately after the construction of the property function instance.
  • execEvaluated函数:这个函数本质上是实现了PropertyFunction的exec接口,生成一个结果的queryIterartor。

这东西就和之前new PFuncSimple的时候一样了。官方例子里面localname那个例子用了这种方法。

这个注册的时候就是用

1
PropertyFunctionRegistry.get().put("http://example/f#search", labelSearch.class) ;

query里面

1
2
PREFIX ext: <http://example/f#>
SELECT * { ?x ext:search 'EF' }

或者直接用java:动态注册.prefix是包名,冒号后面是类名

1
2
PREFIX ext: <java:arq.examples.propertyfunction.>
SELECT * { ?x ext:labelSearch 'EF' }

函数返回值

PFuncSimple的execEvaluated函数返回值有三种:

另外也可以用IterLib提供的函数直接返回空和一个结果的binding。

稍微说一下binding和QueryIterator的关系。QueryIterator接口是public interface QueryIterator extends Closeable, Iterator<Binding>, PrintSerializable,他extends了Iterator<Binding>。其实QueryIterator的iterator就是一个Iterator加了一些其他东西,对于QueryIterPlainWrapper,直接return new QueryIterPlainWrapper(Iterator iter, ExecutionContext context)。

binding本身是一个变量名和值的mapping。同时它使用了chain的形式可以一直找父节点。所以新建binding就是调用BindFactory.binding(Binding parent, Var var, Node node),var是变量,node是值,比如URI的node或者Literal的node。可以用NodeFactory.createLiteral等函数来构造这个node


本文采用创作共用保留署名-非商业-禁止演绎4.0国际许可证,欢迎转载,但转载请注明来自http://thousandhu.github.io,并保持转载后文章内容的完整。本人保留所有版权相关权利。

本文链接:http://thousandhu.github.io/2016/04/27/Sparql自定义propertyFunction/