Preferred SPARQL Combination

I am trying to write an elegant SPARQL that gives me one solution for multiple possible queries. I have a range of items and a range of predicates and I want to get one object. The existence of a single solution is very uncertain, so I give several options. If I am not mistaken, it can be done with the following query:

SELECT ?object
WHERE {
    :subjA|:subjB|:subjC :propA|:propB|:propC ?object.
}
LIMIT 1

      

The real problem is I don't want a solution. I want the order to be :subjA

, then :propA

. Make it clear; I want the first solution in the following list of combinations:

  • :subjA

    :propA

  • :subjA

    :propB

  • :subjA

    :propC

  • :subjB

    :propA

  • :subjB

    :propB

  • :subjB

    :propC

  • :subjC

    :propA

  • :subjC

    :propB

  • :subjC

    :propC

How do I rewrite my query to get the first possible solution?

+3


source to share


2 answers


This is most likely not a valid SPARQL query. You can use |

for a predicate that the property path will then be called, but you will lose the variable binding.

SPARQL returns a set of rows, but you can use lexicographic order, for example. Not sure if this is what you want:

sample data

@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 .

      

request

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

      

result



-------------------------
| 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 |
-------------------------

      

Update

Since a certain order is required, an index for the entities can be used as a workaround (I changed the order :subjB

and :subjC

accordingly :propB

and :propC

to show the difference compared to the lexicographic order):

request

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

      

result



-------------------------
| s      | p      | o   |
=========================
| :subjA | :propA | :o1 |
| :subjA | :propC | :o1 |
| :subjA | :propC | :o2 |
| :subjC | :propB | :o1 |
| :subjC | :propA | :o1 |
| :subjB | :propB | :o1 |
| :subjB | :propB | :o2 |
| :subjB | :propC | :o2 |
-------------------------

      

+3


source


You can do this in two ways. They differ according to your needs alphabetically or not. First for alphabetical sorting:

 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

      

Second way for custom sort:

 Select ?object where {
    {:subjA :propA ?object}
    Union
    {:subjA :propB ?object}
    .......
 } limit 1

      

I write all this with my memory, so there may be some errors in this code.



Add a third way: You can add something like this to your rdf store:

:subjA :order_num 1
:subjB :order_num 2
:subjC :order_num 3
:propA :order_num 1
:propB :order_num 2
:propC :order_num 3

      

And then use a query like this:

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

      

or if you want to use different subjs and props you can add a filter: filter ((? ord_num_sub = 2 or? ord_num_sub = 3) and (? ord_num_prop = 1 or? ord_num_prop = 2))

+1


source







All Articles