问题描述
我正在开发一个Java应用程序,该应用程序使用ARQ通过TDB上的Fuseki端点执行SPARQL查询.
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.
首先,我编写了此SPARQL查询,该查询返回person_ids和每个人的出生地.
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 |
----------------------------------
之后,我添加了一个子查询( https://jena.apache. org/documentation/query/sub-select.html )添加在此出生的其他人,但我得到的亲戚不止一个,而我只需要一个.
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 |
---------------------------------------------------
我尝试添加LIMIT 1子查询,但似乎不起作用(已执行查询,但从未结束)
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
有没有一种方法可以在子查询中仅返回一个结果,或者我不能使用SPARQL来返回结果.
Is there a way to return only one result in the subquery, or can I not do that using SPARQL.
推荐答案
您可以对子查询使用限制
您可以在子查询中使用限制.这是一个示例:
You can use limits with subqueries
You can use limits in subqueries. Here's an example:
select ?x ?y where {
values ?x { 1 2 3 4 }
{
select ?y where {
values ?y { 5 6 7 8 }
}
limit 2
}
}
limit 5
---------
| x | y |
=========
| 1 | 5 |
| 1 | 6 |
| 2 | 5 |
| 2 | 6 |
| 3 | 5 |
---------
如您所见,您从子查询中获得了两个值(5和6),这些值与外部查询中的绑定相结合,总共得到了5行(由于限制).
As you can see, you get two values from the subquery (5 and 6), and these are combined with the bindings from the outer query, from which we get five rows in total (because of the limit).
但是,请记住,子查询是从最内层到最外层的顺序进行评估的.这意味着在您的查询中,
However, keep in mind that subqueries are evaluated from the innermost first, to the outermost. That means that in your query,
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
您正在找到
?place_of_birth_id fb:location.location.people_born_here ?other_person_id .
并将?other_person_id 绑定 out 传递到外部查询中.不过,外部查询的其余部分未使用?other_person_id ,因此它实际上对结果没有任何影响.
and passing the ?other_person_id binding out into the outer query. The rest of the outer query doesn't use ?other_person_id, though, so it doesn't really have any effect on the results.
从概念上讲,您可以将其视为挑选一个人,找到他们的出生地,然后从那个地方出生的人中再抽样一个人.您实际上也可以这样编写查询:
Conceptually, you could look at this as picking a person, finding their place of birth, and sampling one more person from the people born in that place. You can actually write the query like that, too:
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
如果您需要多个
如果每个结果都需要多个其他结果",这将是一个棘手的问题.这就是带有限制的sparql中的嵌套查询中的问题. 如何限制SPARQL解决方案组的大小?.
If you need more than one
This is a much trickier problem if you need more than one "other result" for each result. That's the problem in Nested queries in sparql with limits. There's an approach in How to limit SPARQL solution group size? that can be used for this.
这篇关于SPARQL使用具有限制的子查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!