Пользовательская функция ARQ не работает с конечной точкой fuseki

Я успешно реализовал запросы sparql, используя пользовательские функции ARQ, используя следующее (код пользовательской функции):

public class LevenshteinFilter extends FunctionBase2 {

    public LevenshteinFilter() { super() ; }

    public NodeValue exec(NodeValue value1, NodeValue value2){
        LevenshteinDistance LD=new LevenshteinDistance();
        int i = LD.apply(value1.asString(), value2.asString()); 
        return NodeValue.makeInteger(i); 
    }
}

он отлично работает, когда я запрашиваю модель, загруженную из файла черепахи, например так:

InputStream input = QueryProcessor.class.getClassLoader().getResourceAsStream("full.ttl");
            model = ModelFactory.createMemModelMaker().createModel("default");
            model.read(input,null,"TURTLE"); // null base URI, since model URIs are absolute
            input.close();

с запросом, отправляемым так:

String functionUri = "http://www.example1.org/LevenshteinFunction"; 
        FunctionRegistry.get().put(functionUri , LevenshteinFilter.class);

        String s = "whatever you want";
        String sparql = prefixes+" SELECT DISTINCT ?l WHERE { ?x rdfs:label ?l . " +  "FILTER(fct:LevenshteinFunction(?l, \"" + s + "\") < 4) }";                                              
        Query query = QueryFactory.create(sparql);
        QueryExecution qexec = QueryExecutionFactory.create(query, model); 
        ResultSet rs = qexec.execSelect();

Однако, если я использую рабочую конечную точку fuseki для того же набора данных (full.ttl), как это:

fusekiUrl="http://localhost:3030/ds/query";

отправив запрос следующим образом (используя QueryExecutionFactory.sparqlService(fusekiUrl,query) вместо QueryExecutionFactory.create (query, model)):

String functionUri = "http://www.example1.org/LevenshteinFunction"; 
        FunctionRegistry.get().put(functionUri , LevenshteinFilter.class);

        String s = "whatever you want";
        String sparql = prefixes+" SELECT DISTINCT ?l WHERE { ?x rdfs:label ?l . " + "FILTER(fct:LevenshteinFunction(?l, \"" + s + "\") < 4) }";                                       
        Query query = QueryFactory.create(sparql);
        QueryExecution qexec = QueryExecutionFactory.sparqlService(fusekiUrl,query); 
        ResultSet rs = qexec.execSelect();

Тогда я не получаю никаких результатов обратно. В обоих случаях я распечатал FunctionRegistry, и они содержат одинаковые записи, особенно:

key = http://www.example1.org/LevenshteinFunction value: org.apache.jena.sparql.function.FunctionFactoryAuto@5a45133e

Любая подсказка?

Спасибо

Вернемся к тому вопросу, который я окончательно решил. Было несколько проблем, одна из которых заключается в том, что (очевидно!!) удаленная конечная точка и клиент работают на разных jvms.

Чтобы заставить это работать, сделайте следующее (для глупой пользовательской функции MyFilter - т.е. strlen):

1) Развернуть пользовательские функции классов jar на сервере fuseki

2) Изменить конфигурацию fuseki:

add [] ja:loadClass "my.functions.package.MyFilter"

где реализация MyFilter:

import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.function.FunctionBase1;


public class MyFilter extends FunctionBase1 {

public MyFilter() { super() ; }

public NodeValue exec(NodeValue value1){

        int d = value1.asString().length();
        return NodeValue.makeInteger(new Integer(d)); 
    }
}

3) добавить следующий префикс в контекст:

PREFIX f: <java:my.functions.package.>

Обратите внимание, что "my.functions.package." является пакетом класса MyFilter, а не самого класса -> это означает, что вы никогда не вызываете метод класса в запросах sparql, а только класс, реализующий org.apache.jena.sparql.function.FunctionBaseX, где X - номер аргумента вашей функции фильтра

4) Напишите (например) запрос так:

SELECT DISTINCT ?l
WHERE { ?x skos:prefLabel ?l .  
  FILTER (f:MyFilter(?l) < 20) 
}

РЕДАКТИРОВАТЬ: шаг 2) не является необходимым

0 ответов

Другие вопросы по тегам