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.