SPARQL запрос шаблона zick-zack

У меня есть запрос SPARQL, который имитирует шаблон Zick-Zack, как показано ниже.

?p1 :infector ?p.
?p2 :infector ?p1.
?p3 :infector ?p2.
?p4 :infector ?p3.
?p5 :infector ?p4
.................

В основном, в шаблоне субъект одной тройки используют в качестве объекта для следующего. Есть ли способ обобщить эту модель? Поэтому мне не нужно использовать длинный список переменных (? P-? P5) в шаблоне. Кроме того, я не знаю, сколько таких переменных мне нужно, прежде чем выполнять запрос несколько раз. Следовательно, я не могу придумать определенный набор переменных. Мне нужно что-то общее. Если у вас есть идея сделать этот запрос общим, пожалуйста, дайте мне знать. Я буду очень признателен за любую помощь.

Разъяснение:

У меня есть график RDF, как показано ниже.

<http://ndssl.bi.vt.edu/chicago/dendrogram/experiment_id#7385/cell_id#86304/infectee_pid#446734805/iteration#0> <http://ndssl.bi.vt.edu/chicago/vocab/dendrogram_infector_pid> <http://ndssl.bi.vt.edu/chicago/person/pid#449563560>.

<http://ndssl.bi.vt.edu/chicago/dendrogram/experiment_id#7385/cell_id#86304/infectee_pid#446734805/iteration#0> <http://ndssl.bi.vt.edu/chicago/vocab/dendrogram_infectee_pid> <http://ndssl.bi.vt.edu/chicago/person/pid#446734805>

<http://ndssl.bi.vt.edu/chicago/dendrogram/experiment_id#7385/cell_id#86304/infectee_pid#446753456/iteration#0> <http://ndssl.bi.vt.edu/chicago/vocab/dendrogram_infector_pid> <http://ndssl.bi.vt.edu/chicago/person/pid#446734805>.

<http://ndssl.bi.vt.edu/chicago/dendrogram/experiment_id#7385/cell_id#86304/infectee_pid#446753456/iteration#0> <http://ndssl.bi.vt.edu/chicago/vocab/dendrogram_infectee_pid> <http://ndssl.bi.vt.edu/chicago/person/pid#446753456>.

.......................................................................

Следующий запрос SPARQL может получить существующую цепочку упомянутых выше RDF-графов.

select * from <http://ndssl.bi.vt.edu/chicago/> where
where { 
{
?s <http://ndssl.bi.vt.edu/chicago/vocab/dendrogram_infector_pid> ?o1.
?s <http://ndssl.bi.vt.edu/chicago/vocab/dendrogram_infectee_pid> ?o2
}

{
?s1 <http://ndssl.bi.vt.edu/chicago/vocab/dendrogram_infector_pid> ?o2.
?s1 <http://ndssl.bi.vt.edu/chicago/vocab/dendrogram_infectee_pid> ?o3
}
 ..........................................................................

}

Этот тип цепочки запросов состоит из двух частей, в которых идентификатор контактного лица из первой части запроса используется в качестве инфектора для второй части. В моем запросе у меня много деталей. Есть ли способ обобщить это? Так что вместо того, чтобы использовать так много деталей, я могу просто использовать одну деталь и получить результат. Кстати, мне нужна длина пути и информация о промежуточных узлах.

1 ответ

В основном, в шаблоне субъект одной тройки используют в качестве объекта для следующего. Есть ли способ обобщить эту модель?

Во-первых, обратите внимание, если вы рассматриваете свои тройные паттерны в другом направлении, то это не столько зигзаг, сколько цепочка:

?p5 :infector ?p4 .
?p4 :infector ?p3 .
?p3 :infector ?p2 .
?p2 :infector ?p1 .
?p1 :infector ?p0 .

Это легко записать с помощью пути свойства повторения:

?p5 :infector* ?p0

Вы можете изменить направление, если хотите видеть? P0 появится в тексте вашего запроса первым, поменяв направление пути свойства:

?p0 ^:infector* ?p5

Мне также нужно знать длину пути и информацию о промежуточных узлах.

Поскольку вы говорите о "длине пути", звучит так, будто вы хотите максимальный путь. Это немного усложняет ситуацию, но вы все равно можете это сделать. Вы можете применить подход из Можно ли получить положение элемента в RDF Collection в SPARQL?, Чтобы получить длину пути от "начала до конца", вы можете сделать что-то вроде:

select ?begin ?end (count(?mid) as ?length) {
  ?end :infector* ?mid .
  ?mid :infector* ?begin .
}
group by ?begin ?end

Это найдет длину каждого: пути заражения. Если вам нужны только максимальные пути, вам нужно убедиться, что путь не может быть расширен ни в одном направлении, ни от "начала", ни "конца":

select ?begin ?end (count(?mid) as ?length) {
  ?end :infector* ?mid .
  ?mid :infector* ?begin .

  filter not exists { ?begin :infector ?beginEx }
  filter not exists { ?endEx :infector ?end }
}
group by ?begin ?end

Это требует группировки по переменной? Mid, поэтому вы не можете получить неагрегированную информацию о средних узлах в то же время, когда вы получаете длину, но когда вы не получите длину, вы можете получить информацию о средние узлы:

select * {
  ?end :infector* ?mid .
  ?mid :infector* ?begin .

  filter not exists { ?begin :infector ?beginEx }
  filter not exists { ?endEx :infector ?end }

  #-- information about ?mid, e.g,. 
  #-- ?mid rdfs:label ?midLabel . 
}
Другие вопросы по тегам