Как создать новую переменную в запросе CONSTRUCT - PullRequest
1 голос
/ 01 апреля 2019

Я преобразую данные в одном хранилище данных в другую форму / онтологию / схему, используя SPARQL.

Данные на самом деле являются происхождением, но их можно упростить как последовательность отношений, подобную этой: A produces D + B consumes D.

:A0 :consumes :D0 ;
    :produces :D1, :D2 .
:A1 :produces :D3 .
:A2 :consumes :D1, :D2 ;
    :produces :D4 .
:A3 :consumes :D3, :D4 ;
    :produces :D5, D6 .

(Нет гарантии, что D всегда производится одним A или будет потребляться другим A. Но каждый D будет производиться только одним A.)

Я хотел бы получить информацию о зависимости данных.Пример запроса выглядит так:

CONSTRUCT {
    ?producer :hasNextStage ?consumer .
}
WHERE {
    ?producer :produces ?data .
    OPTIONAL {
            ?consumer :consumes ?data .
            FILTER (?producer != ?consumer)
    }
}

Пока все хорошо.Тем не менее, я хотел бы получить больше информации, скажем, «какой A связан с каким другим A с какими данными», что-то вроде этого:

:A0 :hasInfluence :INFLUENCE .
:INFLUENCE :stage :A2 ;
    :data :D1, :D2 .

Как показано, это требует от меня создания новой переменной (:INFLUENCE) и назначьте ему тройки.Есть ли способ сделать это в SPARQL?

------ ОБНОВЛЕНО ВТОРИЧНЫЙ ВОПРОС ------

Согласно ответу cygri, я изменил запрос на это:

CONSTRUCT {
    ?producer :hasInfluence ?influence .
    ?influence :stage ?consumer ;
        :data ?data .
}
WHERE {
    ?producer :produces ?data .
    OPTIONAL {
            ?consumer :consumes ?data .
            FILTER (?producer != ?consumer)
            BIND (IRI(CONCAT("http://my/ns/#", CONCAT(STRAFTER(STR(?producer), "#"), STRAFTER(STR(?consumer), "#")))) AS ?influence)
    }
}

Однако предложение BIND, похоже, не имеет никакого эффекта.После его сокращения проблема заключается в переменной ?producer: если я использую эту переменную здесь, она не будет работать.Кажется ?producer не связан здесь?(Но FILTER работает.)

Если я уберу это предложение BIND из OPTIONAL, все будет работать нормально.Но это не интуитивно понятно, и мне интересно, почему это не будет работать внутри OPTIONAL?

1 Ответ

1 голос
/ 01 апреля 2019

Самое простое решение состоит в том, чтобы вообще избежать новой переменной в шаблоне CONSTRUCT и просто использовать пустой узел:

CONSTRUCT {
    ?producer :hasInfluence [
        :stage ?consumer;
        :data ?data
    ]
}

Это должно создать желаемую структуру графа.Если вы настаиваете на IRI вместо пустого узла для узла влияния (как вы, вероятно, должны), то вам нужно что-то вроде:

CONSTRUCT {
    ?producer :hasInfluence ?influence.
    ?influence :stage ?consumer;
        :data ?data.
}
WHERE {
    ...
    BIND (IRI(xxx) AS ?influence)
}

Это назначает новый IRI для переменной ?influence и используетэта переменная в шаблоне CONSTRUCT.

Теперь xxx - это просто заполнитель для выражения, которое вычисляет IRI.Вы не предоставили достаточно подробностей, чтобы сказать, что должно быть там.Будет ли один узел влияния для каждого узла данных?Если это так, вы можете взять строковую форму IRI данных: str(?data) и выполнить некоторую замену строки, используя replace(s, search, replace), чтобы сделать хороший уникальный IRI для узла влияния.

...