我是SPARQL和Wikidata的新手。我试图让我的用户搜索Wikidata中的人员,并且仅限人员,我不希望任何结果成为摩托车品牌或任何东西。
所以我在这里玩以下查询:
SELECT ?person ?personLabel WHERE {
?person wdt:P31 wd:Q5.
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en".
?person rdfs:label ?personLabel .
}
FILTER regex(?personLabel, "Albert", "i").
}
LIMIT 10
Run Code Online (Sandbox Code Playgroud)
尽管这最终会返回结果,但它几乎不如我希望的那样快。请注意,如果您使用更大的名称尝试上述查询,它也会超时。
在此处找到的所有示例查询都假定您已经有一个要从其查询的实体。就我而言,您什么也没做,因为我正在尝试查询具有特定名称的人。我可能对正在使用的数据库的内部运行方式做出了一些错误的假设,但是我不确定它们到底是什么。
有任何想法吗?
您可以尝试使用标签代替过滤器:
SELECT ?item ?itemLabel WHERE {
?item wdt:P31 wd:Q5.
?item ?label "Einstein"@en .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Run Code Online (Sandbox Code Playgroud)
在Wikidata查询服务上查看
但是我不确定是否可以使用通配符进行搜索。
使用Wikidata进行自由文本搜索的问题在于,它还没有自由文本索引。如果没有索引,则文本搜索需要为每个标签尝试匹配,这效率不高。我无法提出一个查询“ Albert Einstein”并且没有超时的查询。?person rdfs:label "Albert Einstein"@en .当然,完全匹配()确实有效,但大概不符合您的需求。如果您可以首先以其他方式缩小人员选择的范围,将会有所帮助。
另一方面,DBpedia(http://dbpedia.org/sparql)具有Virtuoso bif:contains可用,因此在那里的运行速度非常快(http://yasgui.org/short/HJeZ4kjp):
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT * WHERE {
?sub a foaf:Person .
?sub rdfs:label ?lbl .
?lbl bif:contains "Albert AND Einstein" .
filter(langMatches(lang(?lbl), "en"))
}
LIMIT 10
Run Code Online (Sandbox Code Playgroud)