【问题标题】:HyperGraphQL- Federating the SPARQL across multiple servicesHyperGraphQL - 跨多个服务联合 SPARQL
【发布时间】: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 &lt;http://localhost:7003/resource/EMPLOYEES/3&gt; 是如何指向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 { &lt;http://localhost:7002/resource/CUSTOMERS/11&gt; }

我们如何解决这个问题?

【问题讨论】:

    标签: graphql sparql ontology


    【解决方案1】:

    我终于弄清楚HyperGraphQL 生成这些SPARQL 的方式如下所示

    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 . }  }  } 
    

    这实际上是发送的

    http://localhost:7003/sparql?query=

    所以它基本上期望7003 上有一个可用的图表,其中包含像&lt;http://localhost:7002/resource/CUSTOMERS/11&gt;?x_1 &lt;http://localhost:7002/resource/vocab/CUSTOMERS_SUPPORTREPID&gt; ?x_1_1 . 这样的客户

    我通过将客户主数据和这种关系从Orders SYS 复制到7003 上的HR SYS 7002 来让它工作,然后这工作得很好。

    但是我认为这违背了SPARQL federation 的目的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-05
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多