【问题标题】:SPARQL query for individuals with same propertiesSPARQL 查询具有相同属性的个人
【发布时间】:2018-01-08 22:47:26
【问题描述】:

我想识别所有与其他人具有相同属性的人。想象一下,有不同的购物清单,上面有不同的物品,可以购买或租用(对象属性)。为了使事情变得更复杂,我还想为停车支付确切的金额并行驶一定距离(数据属性)。同时,有不同的商店提供不同的商品。 作为一个懒惰的人,我想为每个列表确定提供列表中所有项目的商店。

我相信这是question 的概括,但我不知何故无法理解如何做到这一点。

我创建了一些样本个体:

@prefix : <http://www.shopping.org/model#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@base <http://www.shopping.org/model> .

<http://www.shopping.org/model> rdf:type owl:Ontology .

#    Object Properties
:buy rdf:type owl:ObjectProperty .
:rent rdf:type owl:ObjectProperty .

#    Data properties
:distance rdf:type owl:DatatypeProperty .
:parking rdf:type owl:DatatypeProperty .

#    Classes
:Product rdf:type owl:Class .
:ShoppingList rdf:type owl:Class .
:Store rdf:type owl:Class .

#    Individuals
:Apples rdf:type owl:NamedIndividual ,
                 :Product .
:Cereal rdf:type owl:NamedIndividual ,
                 :Product .
:List1 rdf:type owl:NamedIndividual ,
                :ShoppingList ;
       :buy :Apples ,
            :Milk ;
       :distance "9.0"^^xsd:float ;
       :parking "10.0"^^xsd:float .
:List2 rdf:type owl:NamedIndividual ,
                :ShoppingList ;
       :buy :Cereal ,
            :Milk ;
       :rent :TV ;
       :distance "5.0"^^xsd:float ;
       :parking "10.0"^^xsd:float .
:Milk rdf:type owl:NamedIndividual ,
               :Product .
:Store1 rdf:type owl:NamedIndividual ,
                 :Store ;
        :buy :Apples ,
             :Cereal ,
             :Milk ,
             :TV ;
        :distance "9.0"^^xsd:float ;
        :parking "10.0"^^xsd:float .
:Store2 rdf:type owl:NamedIndividual ,
                 :Store ;
        :buy :Cereal ,
             :Milk ;
        :rent :TV ;
        :distance "5.0"^^xsd:float ;
        :parking "10.0"^^xsd:float .
:TV rdf:type owl:NamedIndividual ,
             :Product .

#    General axioms

[ rdf:type owl:AllDisjointClasses ;
  owl:members ( :Product
                :ShoppingList
                :Store
              )
] .

并且还尝试了一些第一个查询。这是我最好的:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX : <http://www.shopping.org/model#>
SELECT DISTINCT ?list ?store ?prop 
WHERE {
    ?list a :ShoppingList . 
    ?store a :Store . 
    ?list ?prop [] . 

    FILTER NOT EXISTS { 
        ?list ?prop ?value . 
        FILTER NOT EXISTS { 
            ?store ?prop ?value . 
        } 
    } 
}
ORDER BY ?list ?store 

但是,此查询返回商店和列表的所有组合,因为每个商店收取 10.0f 的停车费。 如何仅筛选满足列表要求的所有的商店? 另一个假设是,除了 buyrent 之外,可能还存在其他商业模式,以及其他标准,即数据属性,这些也是令人感兴趣的。这就是为什么我不想指定这些属性,而是想使用变量。

这个查询符合我的预期:

PREFIXES [as above]
PREFIX : <http://www.shopping.org/model#>
SELECT DISTINCT ?list ?store 
    WHERE {
        ?list a :ShoppingList . 
        ?store a :Store . 

        FILTER NOT EXISTS { 
            ?compat a owl:DatatypeProperty 
            FILTER NOT EXISTS {
                ?list ?compat ?value . 
                ?store ?compat ?value . 
            }
        } 

        FILTER NOT EXISTS {
            ?subset a owl:ObjectProperty . 
            ?list ?subset ?value . 
            FILTER NOT EXISTS {
                ?store ?subset ?value . 
            }
        }
    }
    ORDER BY ?list ?store

我的错误实际上只是我在过滤器之外定义了 ?prop 。这导致它们成为解决方案的一部分,即我无法通过过滤器删除整个商店。

【问题讨论】:

  • 确实,您提到的解决方案只有在您绑定属性时才有效,例如使用WHERE { VALUES ?prop {:buy} ... 否则,您必须考虑另一种解决方案
  • @AKSW 感谢您的意见。您所说的“其他解决方案”是指另一种查询方式还是在本体中表达这些关系的另一种方式?

标签: sparql rdf owl ontology


【解决方案1】:

如果您愿意具体说明事物需要共有的特定属性,则可以执行以下操作。我已经清理了您的数据,因为它实际上没有必要的前缀声明。如果您希望人们能够使用您提供的内容,提供完整的数据。我没有添加 正确 前缀,但足以让事情正常进行。

样本数据

@prefix :      <urn:ex:> .
@prefix owl:   <file:///home/taylorj/tmp/data.ttl> .
@prefix xsd:   <file:///home/taylorj/tmp/data.ttl> .

:Store1  a         owl:NamedIndividual , :Store ;
        :buy       :Apples , :Cereal , :Milk , :TV ;
        :distance  "9.0"^^owl:float ;
        :parking   "10.0"^^owl:float .

:List2  a          owl:NamedIndividual , :ShoppingList ;
        :buy       :Cereal , :Milk ;
        :distance  "5.0"^^owl:float ;
        :parking   "10.0"^^owl:float ;
        :rent      :TV .

:List1  a          owl:NamedIndividual , :ShoppingList ;
        :buy       :Apples , :Milk ;
        :distance  "9.0"^^owl:float ;
        :parking   "10.0"^^owl:float .

:Store2  a         owl:NamedIndividual , :Store ;
        :buy       :Cereal , :Milk ;
        :distance  "5.0"^^owl:float ;
        :parking   "10.0"^^owl:float ;
        :rent      :TV .

具体解决方案

首先,我们可以解决特定情况,即我们需要一个人为一个属性(buy)拥有另一个人的属性值的子集,并拥有其他属性的相交值(distanceparking)。

查询

prefix : <urn:ex:>

select ?list ?store {

  #-- For each list and store
  ?list a :ShoppingList .
  ?store a :Store .

  #-- Check that they have the same distance and parking.
  ?distance ^:distance ?list, ?store .
  ?parking  ^:parking  ?list, ?store .

  #-- Check that every item to buy (or rent) on the list is also
  #-- in the store to buy (or rent).
  filter not exists {
    values ?get { :buy :rent }
    ?list ?get ?item .
    filter not exists {
      ?store ?get ?item
    }
  }
}

结果

--------------------
| list   | store   |
====================
| :List1 | :Store1 |
| :List2 | :Store2 |
--------------------

一般方法

通常,从消除您不想要的结果的角度进行思考会很有帮助。在这种情况下,您有两种属性:(i) 个体必须具有兼容值的属性,以及 (ii) 一个个体必须具有另一个个体值的超集的属性。检查这些条件中的任何一个是否成立并不难:

prefix : <urn:ex:>

select ?list ?store {

  #-- For each list and store
  ?list a :ShoppingList .
  ?store a :Store .

  #-- Check that for each "compatible property" ?compat,
  #-- there must be some value that the ?list and the
  #-- ?store have in common.
  filter not exists {
    values ?compat { :distance :parking }
    filter not exists {
      ?list ?compat ?value .
      ?store ?compat ?value .
    }
  }

  #-- Check that for each "subset property" ?subset,
  #-- there is no value that the ?list contains that
  #-- the store does not.
  filter not exists {
    values ?subset { :buy :rent }
    ?list ?subset ?value
    filter not exists {
      ?store ?subset ?value
    }
  }
}

结果(相同)

--------------------
| list   | store   |
====================
| :List1 | :Store1 |
| :List2 | :Store2 |
--------------------

【讨论】:

  • 感谢您的回答。我现在包括了整个本体。但是,我不一定有所有属性的列表,这就是我使用变量的原因。我最初并没有说清楚,但现在也将这个假设包含在文本中。如果我实际上可以指定所有相关属性,那么您提出的建议才有效,对吗?换一种说法:要实现我想做什么,我将不得不以另一种方式设计本体?
  • @lixi 你想为不同类型的属性做不同的事情。这些信息必须来自某个地方,对吧?您可以在数据中指定哪个是哪个(例如,添加一个像 :buy :hasPropertyCharacteristic :subsetQuery 这样的三元组),以便您可以在查询中识别应该使用哪些属性。我在查询中使用了硬编码的 values 块,但有关属性的元数据也可以使用。
猜你喜欢
  • 2022-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2021-06-13
  • 2013-08-29
  • 1970-01-01
相关资源
最近更新 更多