SPARQL中嵌套IF语句的语法

And*_*rei 4 rdf sparql virtuoso

我正在尝试运行以下SPARQL查询,但它一直在返回SR171: Transaction timed out.

SELECT ?isBusAvailable WHERE {
  SELECT DISTINCT IF (
  (
  SELECT ?value2 WHERE {
      GRAPH data: { ?obsValueID2 ontology:value ?value2 }
      GRAPH data: { ?obsValueID2 rdf:label "Availability" }
      GRAPH data: { ?obsValueID2 ontology:isObservedValueOf ?obsID2}
      GRAPH data: { ?obsID2 ssn:observationResultTime ?time2 }
      GRAPH data: { ?obsID2 ssn:observedBy ?id2 }
      GRAPH meta: { ?id2 rdf:label "MyBusService" } 
  } ORDER BY DESC (?time2) LIMIT 1) > 1, "Take Bus", (
                       SELECT ?isBikeAvailable WHERE {
                       SELECT DISTINCT IF (
                       (
                       SELECT ?value3 WHERE {
                            GRAPH data: { ?obsValueID3 ontology:value ?value3 }
                            GRAPH data: { ?obsValueID3 rdf:label "Availability" }
                            GRAPH data: { ?obsValueID3 ontology:isObservedValueOf ?obsID3}
                            GRAPH data: { ?obsID3 ssn:observationResultTime ?time3 }
                            GRAPH data: { ?obsID3 ssn:observedBy ?id3 }
                            GRAPH meta: { ?id3 rdf:label "MyBikeService" } 
                       } ORDER BY DESC (?time3) LIMIT 1
                       ) > 0, "Take Bike", "Take Taxi") as ?isBikeAvailable WHERE { ?1 ?2 ?3}})) as ?isBusAvailable WHERE { ?4 ?5 ?6}}
Run Code Online (Sandbox Code Playgroud)

如果我单独运行它,它会在1秒内运行.以下示例有效.

SELECT ?isBusAvailable WHERE {
  SELECT DISTINCT IF (
  (
  SELECT ?value2 WHERE {
      GRAPH data: { ?obsValueID2 ontology:value ?value2 }
      GRAPH data: { ?obsValueID2 rdf:label "Availability" }
      GRAPH data: { ?obsValueID2 ontology:isObservedValueOf ?obsID2}
      GRAPH data: { ?obsID2 ssn:observationResultTime ?time2 }
      GRAPH data: { ?obsID2 ssn:observedBy ?id2 }
      GRAPH meta: { ?id2 rdf:label "MyBusService" } 
  } ORDER BY DESC (?time2) LIMIT 1) > 1, "Take Bus", 'Take Bike') as ?isBusAvailable WHERE { ?4 ?5 ?6}} 
Run Code Online (Sandbox Code Playgroud)

如果第一个查询的结果为true,则返回'Take Bus'; 否则,运行第二个查询,然后返回'Take Bike'或'Take Taxi'.

显然问题在于第二个查询(来自第一个查询的错误条件).在"Take Bus"之后,如果我将第二个查询更改为"Take Bike",它就可以了.

Tal*_*Ted 5

@andrei - 我认为你的?isBusAvailable困惑很重要 - 考虑到你最后返回的文字值,这可能会更好?travelMethod.

在我阅读内容时,这里的问题实际上是如何正确构建嵌套IFs- 问题的标题应该是"在SPARQL中嵌套IF语句的正确语法是什么?"

在简单的流程中,我认为您正在做的是检查可用的公共汽车,并返回"乘坐公共汽车",如果存在的话; 如果没有,你检查一辆可用的自行车,并返回"骑自行车",如果存在的话; 如果没有,你返回"乘坐出租车".在伪代码中IF AVAIL bus, THEN take bus, ELSE ( IF AVAIL bike, THEN take bike, ELSE take taxi ).

@ joshua-taylor关于一件事是正确的 - SELECT DISTINCT IF (…)不是严格有效,但修复只是一个额外的paren包装 - 例如,以下是有效的(和验证) -

SELECT DISTINCT ( IF ( ( 1 = 1 ) 
                     , "true" 
                     , "false" 
                     )           AS ?test ) 
WHERE { ?x ?y ?z } 
LIMIT 1
Run Code Online (Sandbox Code Playgroud)

但是在查询中修复此问题并不会从验证程序获得更好的输出.实际上,替换内部(SELECT ?value … LIMIT 1)查询1会使整个大型查询生效 -

SELECT ?travelMethod 
   WHERE 
     { 
        SELECT DISTINCT 
                         ( IF 
                               (
                                  (
                                     1  > 0
                                  )
                               ,  "Take Bus"
                               ,  (
                                        IF (
                                              (
                                                 1  > 0
                                              )
                                           ,  "Take Bike"
                                           ,  "Take Taxi"
                                           )
                                  )
                               )  AS  ?travelMethod
                         ) 
        FROM         data: 
        WHERE        { ?1  ?2  ?3 }
     }
Run Code Online (Sandbox Code Playgroud)

- 这些内部(SELECT ?value … LIMIT 1)查询也会自行验证 -

SELECT    ?value 
WHERE     
          {
             GRAPH data: { ?obsValueID  ontology:value              ?value          }
             GRAPH data: { ?obsValueID  rdf:label                   "Availability"  }
             GRAPH data: { ?obsValueID  ontology:isObservedValueOf  ?obsID          }
             GRAPH data: { ?obsID       ssn:observationResultTime   ?time           }
             GRAPH data: { ?obsID       ssn:observedBy              ?id             }
             GRAPH meta: { ?id          rdf:label                   "MyBusService"  } 
          }  
ORDER BY  DESC (?time) 
LIMIT     1
Run Code Online (Sandbox Code Playgroud)

我相信以下是有效的语法 - 即使sparql.org验证器扼杀它 - 但我不能确定它执行,因为我没有时间重新调整查询以针对随机端点和数据集运行.如果您重新编写查询以运行DBpedia,那么您可以帮助下一个人!

SELECT ?travelMethod 
   WHERE 
     { 
        SELECT DISTINCT 
                         ( IF 
                               (
                                  (
                                     (  SELECT    ?value 
                                        WHERE     
                                                  {
                                                     GRAPH data: { ?obsValueID  ontology:value              ?value          }
                                                     GRAPH data: { ?obsValueID  rdf:label                   "Availability"  }
                                                     GRAPH data: { ?obsValueID  ontology:isObservedValueOf  ?obsID          }
                                                     GRAPH data: { ?obsID       ssn:observationResultTime   ?time           }
                                                     GRAPH data: { ?obsID       ssn:observedBy              ?id             }
                                                     GRAPH meta: { ?id          rdf:label                   "MyBusService"  } 
                                                  }  
                                        ORDER BY  DESC (?time) 
                                        LIMIT     1
                                     )  > 0
                                  )
                               ,  "Take Bus"
                               ,  (
                                        IF (
                                              (
                                                 (  SELECT    ?value 
                                                    WHERE
                                                              {
                                                                 GRAPH data: { ?obsValueID  ontology:value              ?value           }
                                                                 GRAPH data: { ?obsValueID  rdf:label                   "Availability"   }
                                                                 GRAPH data: { ?obsValueID  ontology:isObservedValueOf  ?obsID           }
                                                                 GRAPH data: { ?obsID       ssn:observationResultTime   ?time            }
                                                                 GRAPH data: { ?obsID       ssn:observedBy              ?id              }
                                                                 GRAPH meta: { ?id          rdf:label                   "MyBikeService"  } 
                                                              } 
                                                    ORDER BY  DESC (?time) 
                                                    LIMIT     1
                                                 )  > 0
                                              )
                                           ,  "Take Bike"
                                           ,  "Take Taxi"
                                           )
                                  )
                               )  AS  ?travelMethod
                         ) 
        FROM         data: 
        WHERE        { ?1  ?2  ?3 }
     }
Run Code Online (Sandbox Code Playgroud)

花了一点时间远离它,并在上面的评论中重新阅读你对数据所说的内容,我可以进一步优化这个查询,这也可以使它更快地执行 -

SELECT ?travelMethod 
   WHERE 
     { 
        SELECT DISTINCT 
                         ( IF 
                               (
                                  (
                                     (  SELECT    ?value 
                                        WHERE     
                                                  {
                                                     GRAPH data: { ?obsValueID  ontology:value              ?value
                                                                             ;  rdf:label                   "Availability"
                                                                             ;  ontology:isObservedValueOf  ?obsID
                                                                 . ?obsID       ssn:observationResultTime   ?time
                                                                             ;  ssn:observedBy              ?id
                                                                 }
                                                     GRAPH meta: { ?id          rdf:label                   "MyBusService"  } 
                                                  }  
                                        ORDER BY  DESC (?time) 
                                        LIMIT     1
                                     )  > 0
                                  )
                               ,  "Take Bus"
                               ,  (
                                        IF (
                                              (
                                                 (  SELECT    ?value 
                                                    WHERE
                                                              {
                                                                 GRAPH data: { ?obsValueID  ontology:value              ?value
                                                                                         ;  rdf:label                   "Availability"
                                                                                         ;  ontology:isObservedValueOf  ?obsID
                                                                             . ?obsID       ssn:observationResultTime   ?time
                                                                                         ;  ssn:observedBy              ?id
                                                                             }
                                                                 GRAPH meta: { ?id          rdf:label                   "MyBikeService"  } 
                                                              } 
                                                    ORDER BY  DESC (?time) 
                                                    LIMIT     1
                                                 )  > 0
                                              )
                                           ,  "Take Bike"
                                           ,  "Take Taxi"
                                           )
                                  )
                               )  AS  ?travelMethod
                         ) 
        FROM         data: 
        WHERE        { ?1  ?2  ?3 }
     }
Run Code Online (Sandbox Code Playgroud)