You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by "Paton, Diego" <di...@teamaol.com> on 2014/11/21 12:51:22 UTC

SPARQL using subquery with limit

Hi,

I am developing a java application that uses ARQ to execute SPARQL queries using a Fuseki endpoint over TDB.

The application needs a query that returns the place of birth of each person and other person that was born in the same place.

To start, I wrote this SPARQL query that returns person_ids and the place of birth of each person.

prefix fb: <http://rdf.freebase.com/ns/>
prefix fn: <http://www.w3.org/2005/xpath-functions#>
select ?person_id ?place_of_birth 
where {
    ?person_id fb:type.object.type fb:people.person .
    ?person_id fb:people.person.place_of_birth ?place_of_birth_id .
    ?place_of_birth_id fb:type.object.name ?place_of_birth .
     FILTER (langMatches(lang(?place_of_birth),"en"))
}
LIMIT 10

----------------------------------
| person_id    | place_of_birth  |
==================================
| fb:m.01vtj38 | "El Centro"@en  |
| fb:m.01vsy7t | "Brixton"@en    |
| fb:m.09prqv  | "Pittsburgh"@en |
----------------------------------

After that, I added a subquery (https://jena.apache.org/documentation/query/sub-select.html) adding other person who was born there, but I get more than one person related and I only need one.


prefix fb: <http://rdf.freebase.com/ns/>
prefix fn: <http://www.w3.org/2005/xpath-functions#>
select ?person_id ?place_of_birth ?other_person_id
where {
    ?person_id fb:type.object.type fb:people.person .
    ?person_id fb:people.person.place_of_birth ?place_of_birth_id .
    ?place_of_birth_id fb:type.object.name ?place_of_birth .
    {
       select  ?other_person_id
       where {
       ?place_of_birth_id fb:location.location.people_born_here ?other_person_id .
       }
     }
     FILTER (langMatches(lang(?place_of_birth),"en"))
}
LIMIT 10

---------------------------------------------------
| person_id    | place_of_birth | other_person_id |
===================================================
| fb:m.01vtj38 | "El Centro"@en | fb:m.01vtj38    |
| fb:m.01vtj38 | "El Centro"@en | fb:m.01vsy7t    |
| fb:m.01vtj38 | "El Centro"@en | fb:m.09prqv     |
---------------------------------------------------

I have tried to add a LIMIT 1 subquery but it seems that does not work ( the query is executed but never ends )

prefix fb: <http://rdf.freebase.com/ns/>
prefix fn: <http://www.w3.org/2005/xpath-functions#>
select ?person_id ?place_of_birth ?other_person_id
where {
    ?person_id fb:type.object.type fb:people.person .
    ?person_id fb:people.person.place_of_birth ?place_of_birth_id .
    ?place_of_birth_id fb:type.object.name ?place_of_birth .
    {
       select  ?other_person_id
       where {
       ?place_of_birth_id fb:location.location.people_born_here ?other_person_id .
       }
       LIMIT 1
     }
     FILTER (langMatches(lang(?place_of_birth),"en"))
}
LIMIT 3


Therefore, is there a way to return only 1 result in the subquery ? or can't do that using SPARQL.

Thanks in advance,
Regards,

Diego.

Re: SPARQL using subquery with limit

Posted by "Paton, Diego" <di...@teamaol.com>.
Hi,

Thanks for your response.  I found it very useful and I was able to make progress.

I was able to return 1 person who was born in the same place using this query thanks to the sample function.

select ?person_id ?place_of_birth (sample(?other_person_idx) as ?other_person_id)
where {
    ?person_id fb:type.object.type fb:people.person .
    ?person_id fb:people.person.place_of_birth ?place_of_birth_id .
    ?place_of_birth_id fb:type.object.name ?place_of_birth .
    FILTER (langMatches(lang(?place_of_birth),"en"))
    ?place_of_birth_id fb:location.location.people_born_here ?other_person_idx .
    filter ( ?other_person_idx != ?person_id )
}
group by ?person_id ?place_of_birth

But I am still don't know how to return 3 people who was born in the same place instead 1 or all of them.
Next query returns all the people who was born in the same place but I would need to limit to 3 ?other_person_id per ?person_id

prefix fb: <http://rdf.freebase.com/ns/>
prefix fn: <http://www.w3.org/2005/xpath-functions#>
select ?person_id ?person ?place_of_birth_id ?place_of_birth ?other_person_id
where {
  { 
    select *
    where {
       ?person_id fb:type.object.type fb:people.person .
       ?person_id fb:type.object.name ?person .
       ?person_id fb:people.person.place_of_birth ?place_of_birth_id .  
       ?place_of_birth_id fb:type.object.name ?place_of_birth .   
       FILTER (langMatches(lang(?person),"en")).
       FILTER (langMatches(lang(?place_of_birth),"en")).
    } 
   } . 
   {
    ?place_of_birth_id fb:location.location.people_born_here ?other_person_id .
    ?other_person_id fb:type.object.name ?other_person .
    FILTER (langMatches(lang(?other_person),"en")).
   }.
   FILTER (?other_person != ?person).
}


---------------------------------------------------------------------------------------------
| person_id    | person             | place_of_birth_id | place_of_birth  | other_person_id |
=============================================================================================
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0hgcf7z    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0gzmy0     |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0hgch2y    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0f9n9c     |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.05f9b0g    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0kv3gm3    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0yn_mjp    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.03y6g7s    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.04jc20b    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.047b47f    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0jysb73    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.062360     |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.06w08c     |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.03wf_x7    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0k4c88     |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.02pzgsp    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.02q8br6    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0y8783z    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0k4c8g     |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.0h7qkjy    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.03h44mh    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.02pp_q_    |
| fb:m.01vtj38 | "Cher"@en          | fb:m.0qzq8        | "El Centro"@en  | fb:m.09csml     |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.026vhlg    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.0b7l1f     |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.0_8m4d1    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.03yksp3    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.089h6g     |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.0b4z4f     |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.0ch2ydf    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.03ksw7     |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.07_k9b     |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.0hhvq8_    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.08xcxm     |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.080hzpr    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.01vwcfd    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.01wwq2c    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.02rq19h    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.03c40tm    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.0h66h09    |
| fb:m.01vsy7t | "David Bowie"@en   | fb:m.0n90z        | "Brixton"@en    | fb:m.0j43m81    |
Regards,

Diego.

On 21 Nov 2014, at 11:51, Diego Paton <di...@teamaol.com> wrote:

> Hi,
> 
> I am developing a java application that uses ARQ to execute SPARQL queries using a Fuseki endpoint over TDB.
> 
> The application needs a query that returns the place of birth of each person and other person that was born in the same place.
> 
> To start, I wrote this SPARQL query that returns person_ids and the place of birth of each person.
> 
> prefix fb: <http://rdf.freebase.com/ns/>
> prefix fn: <http://www.w3.org/2005/xpath-functions#>
> select ?person_id ?place_of_birth 
> where {
>     ?person_id fb:type.object.type fb:people.person .
>     ?person_id fb:people.person.place_of_birth ?place_of_birth_id .
>     ?place_of_birth_id fb:type.object.name ?place_of_birth .
>      FILTER (langMatches(lang(?place_of_birth),"en"))
> }
> LIMIT 10
> 
> ----------------------------------
> | person_id    | place_of_birth  |
> ==================================
> | fb:m.01vtj38 | "El Centro"@en  |
> | fb:m.01vsy7t | "Brixton"@en    |
> | fb:m.09prqv  | "Pittsburgh"@en |
> ----------------------------------
> 
> After that, I added a subquery (https://jena.apache.org/documentation/query/sub-select.html) adding other person who was born there, but I get more than one person related and I only need one.
> 
> 
> prefix fb: <http://rdf.freebase.com/ns/>
> prefix fn: <http://www.w3.org/2005/xpath-functions#>
> select ?person_id ?place_of_birth ?other_person_id
> where {
>     ?person_id fb:type.object.type fb:people.person .
>     ?person_id fb:people.person.place_of_birth ?place_of_birth_id .
>     ?place_of_birth_id fb:type.object.name ?place_of_birth .
>     {
>        select  ?other_person_id
>        where {
>        ?place_of_birth_id fb:location.location.people_born_here ?other_person_id .
>        }
>      }
>      FILTER (langMatches(lang(?place_of_birth),"en"))
> }
> LIMIT 10
> 
> ---------------------------------------------------
> | person_id    | place_of_birth | other_person_id |
> ===================================================
> | fb:m.01vtj38 | "El Centro"@en | fb:m.01vtj38    |
> | fb:m.01vtj38 | "El Centro"@en | fb:m.01vsy7t    |
> | fb:m.01vtj38 | "El Centro"@en | fb:m.09prqv     |
> ---------------------------------------------------
> 
> I have tried to add a LIMIT 1 subquery but it seems that does not work ( the query is executed but never ends )
> 
> prefix fb: <http://rdf.freebase.com/ns/>
> prefix fn: <http://www.w3.org/2005/xpath-functions#>
> select ?person_id ?place_of_birth ?other_person_id
> where {
>     ?person_id fb:type.object.type fb:people.person .
>     ?person_id fb:people.person.place_of_birth ?place_of_birth_id .
>     ?place_of_birth_id fb:type.object.name ?place_of_birth .
>     {
>        select  ?other_person_id
>        where {
>        ?place_of_birth_id fb:location.location.people_born_here ?other_person_id .
>        }
>        LIMIT 1
>      }
>      FILTER (langMatches(lang(?place_of_birth),"en"))
> }
> LIMIT 3
> 
> 
> Therefore, is there a way to return only 1 result in the subquery ? or can't do that using SPARQL.
> 
> Thanks in advance,
> Regards,
> 
> Diego.


Re: SPARQL using subquery with limit

Posted by Andy Seaborne <an...@apache.org>.
On 21/11/14 11:51, Paton, Diego wrote:
> Hi,
>
> I am developing a java application that uses ARQ to execute SPARQL
> queries using a Fuseki endpoint over TDB.
>
> The application needs a query that returns the place of birth of each
> person and other person that was born in the same place.
>
> To start, I wrote this SPARQL query that returns person_ids and the
> place of birth of each person.
>
>     prefix fb: <http://rdf.freebase.com/ns/>
>     prefix fn: <http://www.w3.org/2005/xpath-functions#>
>     select ?person_id ?place_of_birth
>     where {
>          ?person_id fb:type.object.type fb:people.person .
>          ?person_id fb:people.person.place_of_birth ?place_of_birth_id .
>          ?place_of_birth_id fb:type.object.name ?place_of_birth .
>           FILTER (langMatches(lang(?place_of_birth),"en"))
>     }
>     LIMIT 10
>
>     ----------------------------------
>     | person_id    | place_of_birth  |
>     ==================================
>     | fb:m.01vtj38 | "El Centro"@en  |
>     | fb:m.01vsy7t | "Brixton"@en    |
>     | fb:m.09prqv  | "Pittsburgh"@en |
>     ----------------------------------
>
>
> After that, I added a subquery
> (https://jena.apache.org/documentation/query/sub-select.html) adding
> other person who was born there, but I get more than one person related
> and I only need one.
>
>
>     prefix fb: <http://rdf.freebase.com/ns/>
>     prefix fn: <http://www.w3.org/2005/xpath-functions#>
>     select ?person_id ?place_of_birth ?other_person_id
>     where {
>          ?person_id fb:type.object.type fb:people.person .
>          ?person_id fb:people.person.place_of_birth ?place_of_birth_id .
>          ?place_of_birth_id fb:type.object.name ?place_of_birth .
>          {
>             select  ?other_person_id
>             where {
>             ?place_of_birth_id fb:location.location.people_born_here
>     ?other_person_id .
>             }
>           }
>           FILTER (langMatches(lang(?place_of_birth),"en"))
>     }
>     LIMIT 10
>
>     ---------------------------------------------------
>     | person_id    | place_of_birth | other_person_id |
>     ===================================================
>     | fb:m.01vtj38 | "El Centro"@en |*fb:m.01vtj38*    |
>     | fb:m.01vtj38 | "El Centro"@en |*fb:m.01vsy7t*    |
>     | fb:m.01vtj38 | "El Centro"@en |*fb:m.09prqv*     |
>     ---------------------------------------------------
>
>
> I have tried to add a LIMIT 1 subquery but it seems that does not work (
> the query is executed but never ends )
>
>     prefix fb: <http://rdf.freebase.com/ns/>
>     prefix fn: <http://www.w3.org/2005/xpath-functions#>
>     select ?person_id ?place_of_birth ?other_person_id
>     where {
>          ?person_id fb:type.object.type fb:people.person .
>          ?person_id fb:people.person.place_of_birth ?place_of_birth_id .
>          ?place_of_birth_id fb:type.object.name ?place_of_birth .
>          {
>             select  ?other_person_id
>             where {
>             ?place_of_birth_id fb:location.location.people_born_here
>     ?other_person_id .
>             }
>     *  LIMIT 1*
>           }
>           FILTER (langMatches(lang(?place_of_birth),"en"))
>     }
>     LIMIT 3
>
>
> Therefore, is there a way to return only 1 result in the subquery ? or
> can't do that using SPARQL.

Firstly, I hope you are using a reasonably recent version because there 
was a fix in this area -- JENA-711

Second,

     select  ?other_person_id

so the inner select is returning a table of one column and that column 
is not connected to anything in the outer query; ?other_person_id is 
only mentioned in the outer select.

?place_of_birth_id in the inner query is not related to the 
?place_of_birth_id in the outer pattern.  They are in different scopes.

Putting it in the projection may help:

    select  ?other_person_id  ?place_of_birth_id

although I'm not completely clear about the structure of your data

I completely different approach is to use GROUP BY / LIMIT but from your 
description, the subquery, limit-by-resource pattern is what you want.

	Andy


>
> Thanks in advance,
> Regards,
>
> Diego.