首选组合SPARQL

时间:2017-05-05 13:36:12

标签: sparql rdf linked-data

我正在尝试编写一个优雅的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

如何重写我的查询以获得第一个可能的解决方案?

2 个答案:

答案 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))