我正在尝试编写一个优雅的SPARQL,它为多个可能的查询提供了一个解决方案。我有许多主题和一些谓词,我想收到一个对象。单一解决方案的存在非常不确定,所以我给出了多种选择。如果我没有弄错,可以使用以下查询完成:
SELECT ?object
WHERE {
:subjA|:subjB|:subjC :propA|:propB|:propC ?object.
}
LIMIT 1
真正的问题是我不想要任何解决方案。我希望按:subjA
然后:propA
订购。说清楚;我想要以下组合列表中的第一个解决方案:
:subjA
:propA
:subjA
:propB
:subjA
:propC
:subjB
:propA
:subjB
:propB
:subjB
:propC
:subjC
:propA
:subjC
:propB
:subjC
:propC
如何重写我的查询以获得第一个可能的解决方案?
答案 0 :(得分:4)
这肯定不是有效的SPARQL查询。您只能将|
用于谓词,然后将其称为属性路径,但您将失去变量绑定。
SPARQL返回一组行,但您可以使用例如词典顺序。不确定,如果这是你想要的:
@prefix : <http://ex.org/> .
:subjA :propA :o1 .
:subjA :propC :o1 .
:subjB :propB :o1 .
:subjC :propB :o1 .
:subjC :propA :o1 .
:subjA :propC :o2 .
:subjB :propB :o2 .
:subjB :propC :o2 .
PREFIX : <http://ex.org/>
SELECT ?s ?p ?o
WHERE
{ VALUES ?s { :subjA :subjB :subjC }
VALUES ?p { :propA :propB :propC }
?s ?p ?o
}
ORDER BY ?s ?p
-------------------------
| s | p | o |
=========================
| :subjA | :propA | :o1 |
| :subjA | :propC | :o1 |
| :subjA | :propC | :o2 |
| :subjB | :propB | :o1 |
| :subjB | :propB | :o2 |
| :subjB | :propC | :o2 |
| :subjC | :propA | :o1 |
| :subjC | :propB | :o1 |
-------------------------
由于需要使用已定义的订单,因此可以使用实体索引作为变通方法(我更改了:subjB
和:subjC
resp。:propB
和{{1}的顺序显示与词典顺序相比的差异):
:propC
PREFIX : <http://ex.org/>
SELECT ?s ?p ?o
WHERE
{ VALUES (?sid ?s) { (1 :subjA) (2 :subjC) (3 :subjB) }
VALUES (?pid ?p) { (1 :propA) (2 :propC) (3 :propB) }
?s ?p ?o
}
ORDER BY ?sid ?pid
答案 1 :(得分:1)
你可以通过两种方式来做到这一点。根据您的字母排序需求,它们会有所不同。 首先进行字母排序:
Select ?object where {
{Select (min(?sub) as ?msub) where {
?sub :propA|:propB|:propC ?obj1
Filter ( ?sub = :subjA or :sub=?...)
} .
{Select (min(?prop) as ?mrop_by_msub) where {
?msub ?prop ?obj2
Filter ( ?prop = :propA or ?prop=?...)
} .
?msub ?mrop_by_msub ?object
}
Limit 1
自定义排序的第二种方式:
Select ?object where {
{:subjA :propA ?object}
Union
{:subjA :propB ?object}
.......
} limit 1
我在记忆中写下了所有内容,因此此代码中可能存在一些错误。
添加第三种方式: 您可以添加到您的rdf商店:
:subjA :order_num 1
:subjB :order_num 2
:subjC :order_num 3
:propA :order_num 1
:propB :order_num 2
:propC :order_num 3
然后使用这样的查询:
select ?object where{
?sub :order_num ?ord_num_sub .
?prop :order_num ?ord_num_prop .
?sub ?prop ?object
} order by ?ord_num_sub ?ord_num_prop
limit 1
或者如果你想使用不同的subjs和道具你可以添加过滤器: filter((?ord_num_sub = 2或?ord_num_sub = 3)和(?ord_num_prop = 1或?ord_num_prop = 2))