Поиск людей в SPARQL на основе других отношений / Сравнение наборов

Даны объекты:A,:B и:C, которым назначены свойства, тогда как сами эти свойства не являются скалярными, но также являются объектами со свойствами ключа и значения.

@prefix x: <http://example.com/example#> 

x:A x:hasProp x:Prop1 .
x:Prop1 x:Key "1" .
x:Prop1 x:Value "AA" .
x:B x:hasProp x:Prop2 .
x:Prop2 x:Key "1" .
x:Prop2 x:Value "AA" .
x:C x:hasProp x:Prop3 .
x:C x:hasProp x:Prop4 .
x:Prop3 x:Key "1" .
x:Prop3 x:Value "AA" .
x:Prop4 x:Key "2" .
x:Prop4 x:Value "BB" .

Как я могу утверждать, что: A и: B имеют одинаковые свойства, тогда как: A и:C нет? Я новичок в SPARQL и понятия не имею... Я попробовал что-то вроде:

prefix x: <http://example.com/example#> 

select ?another ?k ?v
{x:A x:hasProp ?p .
?p ?k ?v .
?another x:hasProp ?p2 .   
?p2 ?k ?v .
}

но я думаю, что это неправильный путь. Также возвращается:C.

Как легко сравнить два набора в SPARQL?


Дополнительный вопрос: запрос из ответа 1 работает нормально, но только если: используется непосредственно. Использование переменной вместо: A делает:C также для квалификации. Зачем?

Я имею в виду: введите условие, чтобы найти: A

prefix : <http://example.com/example#> 

INSERT DATA {:A rdfs:label "A"}

а затем используйте переменную вместо: A

prefix : <http://example.com/example#> 

select ?other ?k ?v {
  #-- Find ?other such that :A and ?other have
  #-- some property in common,
  ?a rdfs:label "A"
  ?a     :hasProp [ :Key ?k ; :Value ?v ] .
  ?other :hasProp [ :Key ?k ; :Value ?v ] .

  #-- but remove any ?other such that:
  filter not exists { 
#-- (i) :A has a property that ?other doesn't; 
  {
    ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
    filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
     }
  }
  union
  #-- or (ii) ?other has a property that :A doesn't.
  {
    ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
    filter not exists {
         ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
   }
 }
}  
}

Обновить:

prefix : <http://example.com/example#> 

INSERT DATA {
:A rdfs:label "A" .
:A :hasProp :Prop1 .
:Prop1 :Key "1" .
:Prop1 :Value "AA" .

:B :hasProp :Prop2 .
:Prop2 :Key "1" .
:Prop2 :Value "AA" .

:C :hasProp :Prop3 .
:C :hasProp :Prop4 .
:Prop3 :Key "1" .
:Prop3 :Value "AA" .

:Prop4 :Key "2" .
:Prop4 :Value "BB" .
}

Запрос с использованием: A

prefix : <http://example.com/example#> 

select ?other ?k ?v {
   :A    :hasProp [ :Key ?k ; :Value ?v ] .
   ?other :hasProp [ :Key ?k ; :Value ?v ] .
   filter not exists { 
     { :A :hasProp [ :Key ?kk ; :Value ?vv ] .
       filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
       }
     }
     union
     {
      ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists { :A :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
   }
  }
 }

Ответ:

 -------------------  
 |other|  k  | v  
 |A    | "1" | "AA"  
 |B    | "1" | "AA"  
 -------------------  

Запрос с использованием переменной? A:

 prefix : <http://example.com/example#> 

select ?other ?k ?v {
   ?a rdfs:label "A" .
   ?a    :hasProp [ :Key ?k ; :Value ?v ] .
   ?other :hasProp [ :Key ?k ; :Value ?v ] .
   filter not exists { 
     { ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
       filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
       }
     }
     union
     {
      ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists { ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
   }
 }

возвращается

другой кв
А "1" "АА"
Б "1" "АА"
С "1" "АА"

1 ответ

Решение

Почему ваш запрос не возвращает то, что вы хотите...

Это всегда помогает показать результат, который вы на самом деле получаете, потому что тогда вы можете указать, какие части вы не ожидаете. В этом случае ваш запрос возвращает:

---------------------------
| another | k      | v    |
===========================
| :C      | :Value | "AA" |
| :C      | :Key   | "1"  |
| :B      | :Value | "AA" |
| :B      | :Key   | "1"  |
| :A      | :Value | "AA" |
| :A      | :Key   | "1"  |
---------------------------

Это имеет смысл в вашем случае, потому что у C есть данные, о которых вы спрашиваете. Это та часть ваших данных:

x:A x:hasProp x:Prop1 .
x:Prop1 x:Key "1" .
x:Prop1 x:Value "AA" .
…
x:C x:hasProp x:Prop3 .
…
x:Prop3 x:Key "1" .
x:Prop3 x:Value "AA" .

Запрос, который возвращает то, что вы хотите

Вот как я бы написал запрос, который даст вам то, что вы хотите. Достаточно легко найти вещи, которые имеют некоторое общее с :A, Из тех, что вам нужно отфильтровать ?other такой что либо :A имеет свойство, которое ?other нет, или такой, что ?other имеет свойство, которое :A нет,

prefix : <http://example.com/example#> 

select ?other ?k ?v {
  #-- Find ?other such that :A and ?other have
  #-- some property in common,
  :A     :hasProp [ :Key ?k ; :Value ?v ] .
  ?other :hasProp [ :Key ?k ; :Value ?v ] .

  #-- but remove any ?other such that:
  filter not exists { 
    #-- (i) :A has a property that ?other doesn't; 
    {
      :A :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists {
        ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
    union
    #-- or (ii) ?other has a property that :A doesn't.
    {
      ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists {
        :A :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
  }
}
----------------------
| other | k   | v    |
======================
| :B    | "1" | "AA" |
| :A    | "1" | "AA" |
----------------------

Перечисление классов эквивалентности

Фактически, вы можете использовать это обобщение, чтобы перечислить различные классы эквивалентности в данных.

prefix : <http://example.com/example#> 

select distinct ?x ?y {
  ?x :hasProp [] .
  ?y :hasProp [] .

  filter not exists { 
    {
      ?x :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists {
        ?y :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
    union
    {
      ?y :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists {
        ?x :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
  }
}
order by ?x ?y
-----------
| x  | y  |
===========
| :A | :A |
| :A | :B |
| :B | :A |
| :B | :B |
| :C | :C |
-----------
Другие вопросы по тегам