查询 Wikibase:label REGEX 和 STRLEN
Query on Wikibase:label REGEX & STRLEN
我是 SparkQL 和 wikidata 的新手,我正在尝试查询以下内容:
- 男歌手(artists/performers)
- 谁还活着
- 名字 = 6 个字符
- 名字不包含 ("e","i","u")
我在使用给定名称的过滤器时遇到问题(我相信这是因为它们引用了 "SERVICE wikibase:label")。我试过使用 HAVING 无济于事。嵌套查询和过滤是正确的操作还是有更优雅的方法?
#-- Male artists
SELECT DISTINCT ?m ?givennameLabel (STRLEN(?givennameLabel)AS ?Namechars)
?mLabel ?plLabel WHERE {
?m wdt:P31 wd:Q5.
?m wdt:P21 wd:Q6581097.
?m wdt:P735 ?givenname.
?m wdt:P27 ?pl.
?m (wdt:P106/wdt:P279*) wd:Q483501.
OPTIONAL { ?m wdt:P175 ?performer. }
OPTIONAL {?m wdt:P570 ?d }
FILTER (!bound(?d))
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
FILTER (!regex(?givennameLabel,"(e|i|u)")). #no records
FILTER (STRLEN(?givennameLabel) = 6) #no records
} #HAVING (!regex(?givennameLabel,"(e|i|u)")) #returns "Bad aggregate"
LIMIT 50
我认为这样的事情应该可行,尽管它没有成功。
BIND(STRLEN(str(?givennameLabel)) as ?NL)
FILTER (?NL = 6)
好的,我想我找到了问题:看起来你调用了一些 "magic" SERVICE,它创建了一些变量 givennameLabel
。对我来说听起来很奇怪,但这可能会导致变量在过滤时不受约束。如果将整个查询放在子 select 中,它会起作用:
#Male artists
SELECT * WHERE {
{
SELECT DISTINCT ?m ?givennameLabel (STRLEN(?givennameLabel)AS ?Namechars)
?mLabel ?plLabel WHERE {
?m wdt:P31 wd:Q5.
?m wdt:P21 wd:Q6581097.
?m wdt:P735 ?givenname.
?m wdt:P27 ?pl.
?m (wdt:P106/wdt:P279*) wd:Q483501.
OPTIONAL { ?m wdt:P175 ?performer. }
OPTIONAL {?m wdt:P570 ?d }
FILTER (!bound(?d))
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 50
}
FILTER (!regex(?givennameLabel,"(e|i|u)")).
FILTER (STRLEN(?givennameLabel) = 6)
}
更新
建议的查询只考虑 50 个资源,没有 LIMIT 会导致超时。正如 user3240704 所提到的,
另一种解决方案是避免使用 SERVICE
子句并使用 rdfs:label
代替:
#Male artists
SELECT DISTINCT ?m ?givennameLabel (STRLEN(?givennameLabel)AS ?Namechars)
?mLabel ?plLabel
WHERE {
?m wdt:P31 wd:Q5.
?m wdt:P21 wd:Q6581097.
?m wdt:P735 ?givenname.
?m wdt:P27 ?pl.
?m (wdt:P106/wdt:P279*) wd:Q483501.
OPTIONAL { ?m wdt:P175 ?performer. }
OPTIONAL {?m wdt:P570 ?d }
FILTER (!bound(?d))
?givenname rdfs:label ?label
FILTER(LANG(?label) ="en").
FILTER (!regex(?label,"(e|i|u)")).
FILTER (STRLEN(?label) = 6)}
}
LIMIT 50
我是 SparkQL 和 wikidata 的新手,我正在尝试查询以下内容:
- 男歌手(artists/performers)
- 谁还活着
- 名字 = 6 个字符
- 名字不包含 ("e","i","u")
我在使用给定名称的过滤器时遇到问题(我相信这是因为它们引用了 "SERVICE wikibase:label")。我试过使用 HAVING 无济于事。嵌套查询和过滤是正确的操作还是有更优雅的方法?
#-- Male artists
SELECT DISTINCT ?m ?givennameLabel (STRLEN(?givennameLabel)AS ?Namechars)
?mLabel ?plLabel WHERE {
?m wdt:P31 wd:Q5.
?m wdt:P21 wd:Q6581097.
?m wdt:P735 ?givenname.
?m wdt:P27 ?pl.
?m (wdt:P106/wdt:P279*) wd:Q483501.
OPTIONAL { ?m wdt:P175 ?performer. }
OPTIONAL {?m wdt:P570 ?d }
FILTER (!bound(?d))
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
FILTER (!regex(?givennameLabel,"(e|i|u)")). #no records
FILTER (STRLEN(?givennameLabel) = 6) #no records
} #HAVING (!regex(?givennameLabel,"(e|i|u)")) #returns "Bad aggregate"
LIMIT 50
我认为这样的事情应该可行,尽管它没有成功。
BIND(STRLEN(str(?givennameLabel)) as ?NL)
FILTER (?NL = 6)
好的,我想我找到了问题:看起来你调用了一些 "magic" SERVICE,它创建了一些变量 givennameLabel
。对我来说听起来很奇怪,但这可能会导致变量在过滤时不受约束。如果将整个查询放在子 select 中,它会起作用:
#Male artists
SELECT * WHERE {
{
SELECT DISTINCT ?m ?givennameLabel (STRLEN(?givennameLabel)AS ?Namechars)
?mLabel ?plLabel WHERE {
?m wdt:P31 wd:Q5.
?m wdt:P21 wd:Q6581097.
?m wdt:P735 ?givenname.
?m wdt:P27 ?pl.
?m (wdt:P106/wdt:P279*) wd:Q483501.
OPTIONAL { ?m wdt:P175 ?performer. }
OPTIONAL {?m wdt:P570 ?d }
FILTER (!bound(?d))
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 50
}
FILTER (!regex(?givennameLabel,"(e|i|u)")).
FILTER (STRLEN(?givennameLabel) = 6)
}
更新
建议的查询只考虑 50 个资源,没有 LIMIT 会导致超时。正如 user3240704 所提到的,
另一种解决方案是避免使用 SERVICE
子句并使用 rdfs:label
代替:
#Male artists
SELECT DISTINCT ?m ?givennameLabel (STRLEN(?givennameLabel)AS ?Namechars)
?mLabel ?plLabel
WHERE {
?m wdt:P31 wd:Q5.
?m wdt:P21 wd:Q6581097.
?m wdt:P735 ?givenname.
?m wdt:P27 ?pl.
?m (wdt:P106/wdt:P279*) wd:Q483501.
OPTIONAL { ?m wdt:P175 ?performer. }
OPTIONAL {?m wdt:P570 ?d }
FILTER (!bound(?d))
?givenname rdfs:label ?label
FILTER(LANG(?label) ="en").
FILTER (!regex(?label,"(e|i|u)")).
FILTER (STRLEN(?label) = 6)}
}
LIMIT 50