【问题标题】:How to get all of the subjects of a Jena Query?如何获取耶拿查询的所有主题?
【发布时间】:2013-03-04 14:28:41
【问题描述】:

假设我有一些耶拿查询对象:

String query = "SELECT * WHERE{ ?s <some_uri> ?o ...etc. }";
Query q = QueryFactory.create(query, Syntax.syntaxARQ);

在查询中获取三元组的所有主题的最佳方法是什么?最好不必手动进行任何字符串解析/操作。

例如,给定一个查询

SELECT * WHERE {
    ?s ?p ?o;
       ?p2 ?o2.
    ?s2 ?p3 ?o3.
    ?s3 ?p4 ?o4.
    <http://example.com> ?p5 ?o5.
}

我希望返回一些看起来像的列表

[?s, ?s2, ?s3, <http://example.com>]

换句话说,我想要查询中所有主题的列表。即使只有那些是变量的主题或那些是文字/uris的主题也会很有用,但我想在查询中找到所有主题的列表。

我知道有一些方法可以返回结果变量 (Query.getResultVars) 和一些其他信息(请参阅 http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/query/Query.html),但我似乎找不到任何可以专门获取查询主题的内容(列表的所有结果变量也将返回谓词和对象)。

任何帮助表示赞赏。

【问题讨论】:

  • 查询字符串是给定的还是可以更改?因为您的问题可以通过更改查询很容易地解决。
  • 我想我终于明白你的意思了。您不需要结果中的所有主题,而是查询中主题的所有绑定变量,对吗?如果是这样,请在问题中更明显。
  • 为什么不迭代结果变量?你想用结果变量创建一个表吗?如果不是,请举个例子。
  • 另外,我认为您的示例中存在错误。你的预期结果不应该是[s, s2, s3]吗?
  • 为清晰起见进行了编辑。查询字符串是给定的,不能更改。除了在查询中充当主题的任何文字/uris之外,我希望获得查询中主题的所有绑定变量。

标签: java sparql semantic-web jena


【解决方案1】:

有趣的问题。您需要做的是通过查询,并为每个三元组块迭代并查看第一部分。

最可靠的方法是通过元素遍历器来遍历查询的每个部分。在您的情况下,它可能看起来有点过头了,但是查询可以包含各种各样的东西,包括FILTERsOPTIONALs 和嵌套的SELECTs。使用 walker 意味着你可以忽略那些东西,只专注于你想要的:

Query q = QueryFactory.create(query); // SPARQL 1.1

// Remember distinct subjects in this
final Set<Node> subjects = new HashSet<Node>();

// This will walk through all parts of the query
ElementWalker.walk(q.getQueryPattern(),
    // For each element...
    new ElementVisitorBase() {
        // ...when it's a block of triples...
        public void visit(ElementPathBlock el) {
            // ...go through all the triples...
            Iterator<TriplePath> triples = el.patternElts();
            while (triples.hasNext()) {
                // ...and grab the subject
                subjects.add(triples.next().getSubject());
            }
        }
    }
);

【讨论】:

  • 所以,这在直觉上是有道理的,感谢您指出ElementWalkerElementVisitors。但是,此实现似乎不适用于上述查询(或任何其他查询)。我发现很难调试这种访问方法的覆盖;知道可能是什么问题吗?每当我尝试这种覆盖时,我只会返回一个空列表。有人有另一个这样的例子吗?
  • 您需要在 ElementPathBlock 中查找 SPARQL 1.1 以及 ElementTriplesBlock。请参阅 PatternVarsVisitor
  • 就像一个魅力。为了将来参考,我只是在某个地方遗漏了一些东西,或者这实际上很难在这个级别上学习如何使用?除了此处的模糊参考:jena.apache.org/documentation/query/… 之外,我找不到任何示例代码或有关如何执行此操作的信息:而且它似乎没有很好的文档记录。也许我只是愚蠢。
  • 你没有错过任何东西。首先,这些东西对于普通用户来说不是一个常见的需求,所以它不会经常出现(商店实施者往往会在 jena-dev 等上闲逛,并直接询问这个问题)。其次,这部分代码库一直是一个移动目标,而 SPARQL 已标准化,Andy 改进了 ARQ。
【解决方案2】:

可能为时已晚,但另一种方法是利用 Jena ARQ 库并创建给定查询的代数。一旦创建了代数,就可以对其进行编译,并且可以遍历所有三元组(在 where 子句中给出)。代码如下,希望对你有帮助:

Query query = qExec.getQuery(); //qExec is an object of QueryExecutionFactory

// Generate algebra of the query
Op op = Algebra.compile(query);
CustomOpVisitorBase opVisitorBase = new CustomOpVisitorBase();
opVisitorBase.opVisitorWalker(op);
List<Triple> queryTriples = opVisitorBase.triples;

CustomOpVisitor 类如下:

public class CustomOpVisitorBase extends OpVisitorBase {
List<Triple> triples = null;
void opVisitorWalker(Op op) {
    OpWalker.walk(op, this);
}

@Override
public void visit(final OpBGP opBGP) {
    triples = opBGP.getPattern().getList();
}
}

遍历Triples列表并使用给定的属性函数,例如triple.getSubject()等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    相关资源
    最近更新 更多