在 Sesame 中使用一组谓词到达同一个对象
Reach the same object with a set of predicates in Sesame
假设 (s,p,o) 和列表,我想在 Sesame 中使用模型结构并检查是否可以使用主题 s、谓词列表并在最后到达 o。
例如我们说有一条路径,如果对于(s,p,o)和{p1,p2,p3},存在下面的三元组:
(s,p1,o1) , (o1,p2,o2), (o2,p3,o)
在Sesame或者Model结构中有没有可能?
执行此操作的最简单方法可能是通过 SPARQL 查询。
查询将使用 属性 路径表达式来表达此路径。由于您想知道给定起点和终点是否存在路径,我假设 "yes" 或 "no" 答案就足够了。所以我们可以做一个布尔 ASK 查询:
ASK WHERE { :s (:p1|:p2|:p3)+ :o . }
这将 return true
如果在 :s
和 :o
之间存在任何长度的路径,它由属性 :p1
、:p2
, 和 :p3
.
由于您不能直接在 Model
上执行 SPARQL 查询,您需要先创建一个 in-memory Repository
并将 Model
添加到其中做查询,像这样:
Model model = ...; // your model
// create and initialize a temporary in-memory store
Repository rep = new SailRepository(new MemoryStore());
rep.initialize();
try (RepositoryConnection conn = rep.getConnection()) {
// load the model into the repository
conn.add(model);
// execute the query
String query = "ASK WHERE { :s (:p1|:p2|:p3)+ :o . }";
boolean pathExists = conn.prepareBooleanQuery(query).evaluate();
}
或者,您可以通过简单的递归方法自己实现路径遍历。
Model model = ...; // your model
IRI start = ... ; // your start point :s
IRI end = ...; // your end point :o .
IRI p1 = ...;
IRI p2 = ...;
IRI p3 = ... ;
boolean pathExists = pathExists(model, start, end, p1, p2, p3);
实际的方法是这样的:
boolean pathExists(Model m, IRI start, IRI end, IRI... properties) {
for(IRI p: properties) {
Model fromStart = m.filter(start, p, null);
if (fromStart.contains(start, p, end)) {
return true;
}
else {
for (Value obj: fromStart.objects()) {
if (obj instanceof Resource) {
if(pathExists(m, obj, end, properties)) {
return true;
}
}
}
}
}
return false;
}
...您可能需要稍微扩展一下(使用访问过的中间节点列表以避免无限循环),但它说明了我希望的基本原理。无论如何,使用 SPARQL 查询要容易得多。
假设 (s,p,o) 和列表,我想在 Sesame 中使用模型结构并检查是否可以使用主题 s、谓词列表并在最后到达 o。
例如我们说有一条路径,如果对于(s,p,o)和{p1,p2,p3},存在下面的三元组: (s,p1,o1) , (o1,p2,o2), (o2,p3,o)
在Sesame或者Model结构中有没有可能?
执行此操作的最简单方法可能是通过 SPARQL 查询。
查询将使用 属性 路径表达式来表达此路径。由于您想知道给定起点和终点是否存在路径,我假设 "yes" 或 "no" 答案就足够了。所以我们可以做一个布尔 ASK 查询:
ASK WHERE { :s (:p1|:p2|:p3)+ :o . }
这将 return true
如果在 :s
和 :o
之间存在任何长度的路径,它由属性 :p1
、:p2
, 和 :p3
.
由于您不能直接在 Model
上执行 SPARQL 查询,您需要先创建一个 in-memory Repository
并将 Model
添加到其中做查询,像这样:
Model model = ...; // your model
// create and initialize a temporary in-memory store
Repository rep = new SailRepository(new MemoryStore());
rep.initialize();
try (RepositoryConnection conn = rep.getConnection()) {
// load the model into the repository
conn.add(model);
// execute the query
String query = "ASK WHERE { :s (:p1|:p2|:p3)+ :o . }";
boolean pathExists = conn.prepareBooleanQuery(query).evaluate();
}
或者,您可以通过简单的递归方法自己实现路径遍历。
Model model = ...; // your model
IRI start = ... ; // your start point :s
IRI end = ...; // your end point :o .
IRI p1 = ...;
IRI p2 = ...;
IRI p3 = ... ;
boolean pathExists = pathExists(model, start, end, p1, p2, p3);
实际的方法是这样的:
boolean pathExists(Model m, IRI start, IRI end, IRI... properties) {
for(IRI p: properties) {
Model fromStart = m.filter(start, p, null);
if (fromStart.contains(start, p, end)) {
return true;
}
else {
for (Value obj: fromStart.objects()) {
if (obj instanceof Resource) {
if(pathExists(m, obj, end, properties)) {
return true;
}
}
}
}
}
return false;
}
...您可能需要稍微扩展一下(使用访问过的中间节点列表以避免无限循环),但它说明了我希望的基本原理。无论如何,使用 SPARQL 查询要容易得多。