应该如何使用 SPARQL 按行业筛选公司列表?

How should one filter a list of companies by industry using SPARQL?

我正在尝试使用 dbpedia 和 sparql 创建特定行业类型 (PaaS/SaaS) 内的公司列表。我阅读了 this post on creating a list of companies with a certain number of employees,我想在 sparql 查询中过滤特定行业,例如:

https://gist.github.com/szydan/e801fa687587d9eb0f6a

我试过这个查询(省略前缀):

CONSTRUCT{
    ?iri a dbpedia-owl:Company;
         foaf:name ?companyName;
         dbpedia-owl:abstract ?description;
         owl:sameAs ?sameAs;
     dbpedia:countryCode ?countryCode;
         sindicetech:locationName ?locationName;
         sindicetech:locationCityName ?locationCityName
}WHERE{
  ?iri a dbpedia-owl:Company.
  OPTIONAL{  
       ?iri dbpedia-owl:abstract ?description.
       FILTER( lang(?description) = "en")
       FILTER (regex(?description, '^platform$')) .
  }
  {
    OPTIONAL{  
      ?iri foaf:name ?companyName.
      FILTER( lang(?companyName) = "en")
    }
  }UNION{
    OPTIONAL{     
      ?iri rdfs:label ?companyName .
      FILTER( lang(?companyName) = "en")
    }
  }
  OPTIONAL{     
      ?iri owl:sameAs ?sameAs
  } 
  {
    OPTIONAL{     
      ?iri dbpedia:locationCountry ?country.
      ?country dbpedia:countryCode ?countryCode 
      FILTER( lang(?countryCode) = "en")
    }
  }UNION{  
    OPTIONAL{     
      ?iri dbpedia-owl:locationCountry ?country.
      ?country dbpedia:countryCode ?countryCode 
      FILTER( lang(?countryCode) = "en")
    } 
  }
  OPTIONAL{
      ?iri dbpedia-owl:location ?location.
      ?location dbpedia:name ?locationName
      FILTER( lang(?locationName) = "en")
  }
  OPTIONAL{
      ?iri dbpedia-owl:locationCity ?locationCity.
      ?locationCity rdfs:label ?locationCityName
      FILTER( lang(?locationCityName) = "en")

  }
}
LIMIT 100

看看我是否能找到平台即服务公司...但我得到的各种结果在描述中都没有这个词。也许 FILTER (regex(?description, '^platform$')) 正则表达式是错误的?有什么方法可以过滤:

?industrySector dbpedia-owl:industry <http://dbpedia.org/resource/Platform_as_a_service>

或者我应该尝试通过本体过滤来缩小范围?

http://mappings.dbpedia.org/index.php/OntologyProperty:Industry

我正在使用 DBPEDIA's Virtuoso 来测试这些查询,理想情况下,我想使用 CONSTRUCT 查询获得类别的 RDF 层次结构,它会提供特定行业内的所有公司,例如作为 PaaS、SaaS 等。但我不喜欢 CONSTRUCT 查询,我会听取任何建议!

改进您的查询

首先,两个注意事项。

  1. 您应该将语言标签与 langMatches 进行比较,而不是 lang(…) = ….
  2. SPARQL 1.1 包括 属性 可以使用交替的路径,以及 values,您可以借此为变量指定允许的值。这意味着代替:
  {
    OPTIONAL{  
      ?iri foaf:name ?companyName.
      FILTER( lang(?companyName) = "en")
    }
  }UNION{
    OPTIONAL{     
      ?iri rdfs:label ?companyName .
      FILTER( lang(?companyName) = "en")
    }
  }

任一

optional { 
  ?iri rdfs:label|foaf:name ?companyName .
  filter langMatches(lang(?companyName),"en")
}

values ?nameProperty { rdfs:label foaf:name }
optional { 
  ?iri ?nameProperty ?companyName .
  filter langMatches(lang(?companyName),"en")
}

属性 路径也可以使查询的其他部分更短。例如,

?iri dbpedia-owl:locationCity ?locationCity.
?locationCity rdfs:label ?locationCityName

可以是:

?iri dbpedia-owl:locationCity/rdfs:label ?locationCityName

因为您没有在任何地方使用 ?locationCity

最后,关于

i'm getting all kinds of results that don't have that word in the description. Perhaps the FILTER (regex(?description, '^platform$')) regex is wrong?

正则表达式并没有完全按照您的要求执行:

FILTER (regex(?description, '^platform$'))

只有当字符串中的字符正好是 "platform" 时才会匹配。您似乎更想检查描述 是否包含 平台一词,在这种情况下,您可以使用 contains,如 包含(?说明,"platform")。但即使你这样更新,你也会有

optional {
  ?iri dbpedia-owl:abstract ?description.
  filter contains(?description,"platform")
  filter langMatches(lang(?description),"en")
}

并且它仍在 可选 块中。 optional 的全部意义在于,即使 optional 部分不匹配,您也可以获得结果。如果你想要求有一个包含单词平台的描述,不要让它成为可选的。

之后,您的查询变为:

prefix sindicetech: <urn:ex:sindicetech:>

construct {
    ?iri a dbpedia-owl:Company ;
         foaf:name ?companyName ;
         dbpedia-owl:abstract ?description ;
         owl:sameAs ?sameAs ;
         dbpedia:countryCode ?countryCode ;
         sindicetech:locationName ?locationName ;
         sindicetech:locationCityName ?locationCityName
}
where {
  ?iri a dbpedia-owl:Company ;
       dbpedia-owl:abstract ?description .
  filter langMatches(lang(?description),"en") .
  filter contains(?description,"platform") .
  optional {
    ?iri foaf:name|rdfs:label ?companyName.
    filter langMatches(lang(?companyName),"en")
  }
  optional {     
    ?iri owl:sameAs ?sameAs
  } 
  optional {
    ?iri (dbpedia:locationCountry|dbpedia-owl:locationCountry)/dbpedia:countryCode ?countryCode .
    filter langMatches(lang(?countryCode),"en")
  }
  optional {
    ?iri dbpedia-owl:location/dbpedia:name ?locationName
    filter langMatches(lang(?locationName),"en")
  }
  optional {
    ?iri dbpedia-owl:locationCity/rdfs:label ?locationCityName
    filter langMatches(lang(?locationCityName),"en")
  }
}
limit 100

SPARQL results

您可以看到结果是关于描述中包含 "platform" 的公司。

请注意,其中 none 个具有任何 dbpedia:countryCode 属性。我不知道你在哪里发现 属性,但它似乎没有在 DBpedia 中的任何地方使用。查询 select (count(*) as ?n) { ?x dbpedia:countryCode ?y } returns 0.

一种不同的方法

Is there a way I could filter for:

?industrySector dbpedia-owl:industry <http://dbpedia.org/resource/Platform_as_a_service>

如果您查看 http://dbpedia.org/resource/Platform_as_a_service,您会发现它通过几个不同的属性与许多公司(但不是那么多)相关:

您可以通过任何 属性 询问任何与此相关的公司。例如,

select distinct ?company where {
  ?company a dbpedia-owl:Company ;
           ?property dbpedia:Platform_as_a_service .
}

SPARQL results

您也可以使用该方法获取构造的更多详细信息。我最终会得到这样的结果:

prefix sindicetech: <urn:ex:sindicetech:>

construct {
  ?company a dbpedia-owl:Company ;
           foaf:name ?label ;
           dbpedia-owl:abstract ?abstract ;
           owl:sameAs ?_company ;
           sindicetech:location [ sindicetech:city ?city ;
                                  sindicetech:country ?country ] .
}
where {
  ?company a dbpedia-owl:Company ;
           ?property dbpedia:Platform_as_a_service ;
           rdfs:label ?label ;
           dbpedia-owl:abstract ?abstract .
  filter langMatches(lang(?label),"en")
  filter langMatches(lang(?abstract),"en")
  optional {
    ?company owl:sameAs ?_company
  }
  optional { 
    ?company dbpedia-owl:location [ rdfs:label ?city ;
                                    dbpedia-owl:country/rdfs:label ?country ] .
    filter langMatches(lang(?city),"en")
    filter langMatches(lang(?country),"en")
  }
}

SPARQL results