【发布时间】:2020-06-14 18:11:29
【问题描述】:
我不确定是我使用 HyperGraphQL 的方式还是我对 SPARQL/RDF 的有限了解,任何指针都将不胜感激。
我正在尝试设置多个 SPARQL 端点,并希望能够创建一个能够跨越这些端点的图形。
我尝试使用以下 chinook.db 并将这些数据拆分为 3 个不同的 SPARQL 服务,如下所示:
我正在尝试创建跨这些服务边界的 SPARQL 链接,例如Orders 服务中的customers 对象具有指向HR 服务中的employees 对象的链接,因此当我查询Customer 时,我能够获得(Orders)Customer.SupportedRep --> (HR)Employee。基本上我应该能够获得支持该客户的员工详细信息。
我的配置如下:
1. chinook.json
{
"name": "chinook-hgql",
"schema": "chinook.graphql",
"server": {
"port": 8889,
"graphql": "/graphql",
"graphiql": "/graphiql"
},
"services": [
{
"id": "chinook-orders-sparql",
"type": "LocalModelSPARQLService",
"filepath": "chinook/chinook-orders.ttl",
"filetype": "TTL"
},
{
"id": "chinook-hr-sparql",
"type": "SPARQLEndpointService",
"url": "http://localhost:7003/sparql",
"graph": "",
"user": "",
"password": ""
}
]
}
2:架构文件:chinook.graphql
type __Context {
Customers: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS")
Employees: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES")
label: _@href(iri: "http://www.w3.org/2000/01/rdf-schema#label")
comment: _@href(iri: "http://www.w3.org/2000/01/rdf-schema#comment")
customerId: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_CUSTOMERID")
customerFirstName: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_FIRSTNAME")
customerLastName: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_LASTNAME")
customerCompany: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_COMPANY")
customerAddress: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_ADDRESS")
customerCity: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_CITY")
customerState: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_STATE")
customerCountry: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_COUNTRY")
customerPostalCode: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_POSTALCODE")
customerPhone: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_PHONE")
customerFax: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_FAX")
customerEmail: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_EMAIL")
SupportRep: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_SUPPORTREPID")
employeeId: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_EMPLOYEEID")
employeeFirstName: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_FIRSTNAME")
employeeLastName: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_LASTNAME")
employeeTitle: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_TITLE")
employeeReportsTo: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_REPORTSTO")
employeeBirthDate: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_BIRTHDATE")
employeeHireDate: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_HIREDATE")
employeeAddress: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_ADDRESS")
employeeCity: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_CITY")
employeeState: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_STATE")
employeeCountry: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_COUNTRY")
employeePostalCode: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_POSTALCODE")
employeePhone: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_PHONE")
employeeFax: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_FAX")
employeeEmail: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_EMAIL")
}
type Customers @service(id:"chinook-orders-sparql") {
customerId: String @service(id:"chinook-orders-sparql")
customerFirstName: String @service(id:"chinook-orders-sparql")
customerLastName: String @service(id:"chinook-orders-sparql")
customerCompany: String @service(id:"chinook-orders-sparql")
customerAddress: String @service(id:"chinook-orders-sparql")
customerCity: String @service(id:"chinook-orders-sparql")
customerState: String @service(id:"chinook-orders-sparql")
customerCountry: String @service(id:"chinook-orders-sparql")
customerPostalCode: String @service(id:"chinook-orders-sparql")
customerPhone: String @service(id:"chinook-orders-sparql")
customerFax: String @service(id:"chinook-orders-sparql")
customerEmail: String @service(id:"chinook-orders-sparql")
SupportRep: Employees @service(id:"chinook-hr-sparql")
}
type Employees @service(id:"chinook-hr-sparql") {
employeeId: String @service(id:"chinook-hr-sparql")
employeeFirstName: String @service(id:"chinook-hr-sparql")
employeeLastName: String @service(id:"chinook-hr-sparql")
employeeTitle: String @service(id:"chinook-hr-sparql")
employeeReportsTo: Employees @service(id:"chinook-hr-sparql")
employeeBirthDate: String @service(id:"chinook-hr-sparql")
employeeHireDate: String @service(id:"chinook-hr-sparql")
employeeAddress: String @service(id:"chinook-hr-sparql")
employeeCity: String @service(id:"chinook-hr-sparql")
employeeState: String @service(id:"chinook-hr-sparql")
employeeCountry: String @service(id:"chinook-hr-sparql")
employeePostalCode: String @service(id:"chinook-hr-sparql")
employeePhone: String @service(id:"chinook-hr-sparql")
employeeFax: String @service(id:"chinook-hr-sparql")
employeeEmail: String @service(id:"chinook-hr-sparql")
}
请注意我是如何尝试在上面建立这种关系的,这就是我遇到问题的地方:
SupportRep:员工@service(id:"chinook-hr-sparql")
在我的 TTL 文件中的数据中,我还更改了 SupportRep 的链接,通过手动编辑值来显示 HR 系统的 URI 的链接以显示以下内容:
<http://localhost:7002/resource/CUSTOMERS/1> rdf:type owl:NamedIndividual ,
vocab:CUSTOMERS ;
vocab:CUSTOMERS_ADDRESS "Av. Brigadeiro Faria Lima, 2170" ;
vocab:CUSTOMERS_CITY "São José dos Campos" ;
vocab:CUSTOMERS_COMPANY "Embraer - Empresa Brasileira de Aeronáutica S.A." ;
vocab:CUSTOMERS_COUNTRY "Brazil" ;
vocab:CUSTOMERS_CUSTOMERID 1 ;
vocab:CUSTOMERS_EMAIL "luisg@embraer.com.br" ;
vocab:CUSTOMERS_FAX "+55 (12) 3923-5566" ;
vocab:CUSTOMERS_FIRSTNAME "Luís" ;
vocab:CUSTOMERS_LASTNAME "Gonçalves" ;
vocab:CUSTOMERS_PHONE "+55 (12) 3923-5555" ;
vocab:CUSTOMERS_POSTALCODE "12227-000" ;
vocab:CUSTOMERS_STATE "SP" ;
vocab:CUSTOMERS_SUPPORTREPID <http://localhost:7003/resource/EMPLOYEES/3> ;
rdfs:label "CUSTOMERS #1" .
请注意vocab:CUSTOMERS_SUPPORTREPID <http://localhost:7003/resource/EMPLOYEES/3> 是如何指向port 7003 上的外部URL 而不是7002
当我尝试获取客户的 SupportRep 名称时,HyperGraphQL 上的查询失败并显示以下消息:
java.util.concurrent.ExecutionException: HttpException: 400 HTTP 400 error making the query:
Parse error: SELECT * WHERE { VALUES ?x_2 { <http://localhost:7002/resource/CUSTOMERS/11> } OPTIONAL { ?x_2 <http://localhost:7002/resource/vocab/CUSTOMERS_SUPPORTREPID> ?x_2_1 . ?x_2_1 a <http://localhost:7003/resource/vocab/EMPLOYEES> OPTIONAL { ?x_2_1 <http://localhost:7003/resource/vocab/EMPLOYEES_FIRSTNAME> ?x_2_1_1 } } }
Lexical error at line 3, column 11. Encountered: " " (32), after : "VALUES"
at java.util.concurrent.FutureTask.report(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at org.hypergraphql.datafetching.services.SPARQLEndpointService.iterateFutureResults(SPARQLEndpointService.java:86)
at org.hypergraphql.datafetching.services.SPARQLEndpointService.executeQuery(SPARQLEndpointService.java:69)
at org.hypergraphql.datafetching.ExecutionTreeNode.generateTreeModel(ExecutionTreeNode.java:357)
at org.hypergraphql.datafetching.FetchingExecution.call(FetchingExecution.java:21)
at org.hypergraphql.datafetching.FetchingExecution.call(FetchingExecution.java:8)]
谁能帮我理解我的方法有什么问题,或者我该如何解决这个问题?
更新 1:
我终于设法让日志记录正常工作,这是我在日志中看到的:
[pool-5-thread-1] DEBUG org.hypergraphql.datafetching.SPARQLEndpointExecution - SELECT * WHERE { VALUES ?x_1 { <http://localhost:7002/resource/CUSTOMERS/11> } OPTIONAL { ?x_1 <http://localhost:7002/resource/vocab/CUSTOMERS_SUPPORTREPID> ?x_1_1 .?x_1_1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://localhost:7003/resource/vocab/EMPLOYEES> . OPTIONAL { ?x_1_1 <http://localhost:7003/resource/vocab/EMPLOYEES_FIRSTNAME> ?x_1_1_1 . } } }
[pool-5-thread-1] DEBUG org.apache.jena.riot.web.HttpOp - [1] GET http://localhost:7003/sparql?query=SELECT++*%0AWHERE%0A++%7B+VALUES+%3Fx_1+%7B+%3Chttp%3A%2F%2Flocalhost%3A7002%2Fresource%2FCUSTOMERS%2F11%3E+%7D%0A++++OPTIONAL%0A++++++%7B+%3Fx_1++++%3Chttp%3A%2F%2Flocalhost%3A7002%2Fresource%2Fvocab%2FCUSTOMERS_SUPPORTREPID%3E++%3Fx_1_1+.%0A++++++++%3Fx_1_1++a+++++++++++++++++++++%3Chttp%3A%2F%2Flocalhost%3A7003%2Fresource%2Fvocab%2FEMPLOYEES%3E%0A++++++++OPTIONAL%0A++++++++++%7B+%3Fx_1_1++%3Chttp%3A%2F%2Flocalhost%3A7003%2Fresource%2Fvocab%2FEMPLOYEES_FIRSTNAME%3E++%3Fx_1_1_1+%7D%0A++++++%7D%0A++%7D%0A
所以,它实际上是在调用外部SPARQL endpoint,但是http://localhost:7003/sparql 的端点对此一无所知
{ VALUES ?x_1 { <http://localhost:7002/resource/CUSTOMERS/11> }
我们如何解决这个问题?
【问题讨论】: