СОЮЗ и пересечение с использованием запросов SPARQL
Я конвертирую пользовательские запросы в SPARQL. Например, когда пользователь говорит "abc", это означает, что нужно указать все узлы заданного типа, у которых есть некоторый атрибут с именем "abc". В качестве продолжения этого, если пользователь говорит "abc or (pqr и lmn)", мне нужно найти все узлы данного типа, для которых некоторый атрибут имеет значение "abc or (pqr and lmn)". Вот запрос, который я предложил:
SELECT DISTINCT ?node, ?type
WHERE
{
{
?node a ?type .
FILTER ( ?type != <sometype>)
}
{
{
?node ?reln0 ?obj0 .
FILTER ( regex(str(?obj0), 'abc', "i") )
}
UNION
{
{
?node ?reln1 ?obj1 .
FILTER ( regex(str(?obj1), 'pqr', "i") )
}
{
?node ?reln2 ?obj2 .
FILTER ( regex(str(?obj2), 'lmn', "i") )
}
}
}
}
ORDER BY ?node
Но это не дает правильных результатов. Что-то не так с приведенным выше запросом? Я не хочу использовать следующее, потому что мне нужно генерировать условия динамически, и каждое предложение должно быть отдельным.
FILTER (regex(str(?obj2), 'abc', "i") || regex(str(?obj2), 'pqr', "i") && regex(str(?obj2), 'lmn', "i"))
1 ответ
Я конкретизировал ваш запрос следующим образом (поместив определенный тип для первого фильтра):
PREFIX : <http://example.org/>
SELECT DISTINCT ?node ?type
WHERE
{
{
?node a ?type .
FILTER ( ?type != :Type1 )
}
{
{
?node ?reln0 ?obj0 .
FILTER ( regex(str(?obj0), 'abc', "i") )
}
UNION
{
{
?node ?reln1 ?obj1 .
FILTER ( regex(str(?obj1), 'pqr', "i") )
}
{
?node ?reln2 ?obj2 .
FILTER ( regex(str(?obj2), 'lmn', "i") )
}
}
}
}
ORDER BY ?node
Затем я сгенерировал следующие данные:
@prefix : <http://example.org/> .
:n1 a :Type2 ; # keep
:r0 :NodeABC .
:n2 a :Type2 ;
:r0 :NodeBCD .
:n3 a :Type2 ; # keep
:r1 :NodePQR ;
:r2 :NodeLMN .
:n4 a :Type2 ;
:r1 :NodeQRS ;
:r2 :NodeLMN .
:n5 a :Type2 ;
:r1 :NodePQR ;
:r2 :NodeMNO .
:n6 a :Type2 ;
:r1 :NodeQRS ;
:r2 :NodeMNO .
Только :n1
а также :n3
должны быть сохранены. Я могу запустить это с помощью командной строки Jena ARQ, или на основе Redlandroqet
и я получаю эти правила в обоих случаях.
С ARQ:
$ arq --data data.n3 --query query.sparql
-----------------
| node | type |
=================
| :n1 | :Type2 |
| :n3 | :Type2 |
-----------------
$ arq --version
Jena: VERSION: 2.10.0
Jena: BUILD_DATE: 2013-02-20T12:04:26+0000
ARQ: VERSION: 2.10.0
ARQ: BUILD_DATE: 2013-02-20T12:04:26+0000
С roqet
:
$ roqet query.sparql -D data.n3 -r table
roqet: Querying from file query.sparql
--------------------------------------------------------------
| node | type |
==============================================================
| uri<http://example.org/n1> | uri<http://example.org/Type2> |
| uri<http://example.org/n3> | uri<http://example.org/Type2> |
--------------------------------------------------------------
$ roqet -v
0.9.28