4

次のように、SPARQL を使用して、同じサブジェクトが同じプロパティに対して複数のオブジェクトを持つトリプルを返そうとしています。

example:subject1 example:property example:object1
example:subject1 example:property example:object2

このようなクエリでは、プロパティ パスを使用する必要があるように感じます。

SELECT ?subject WHERE {
  ?subject example:property{2} ?object .
}

Jena 2.6.4 を使用してこのプロパティ パス クエリを実行していますが、結果が得られません。これはイエナのせい?または、クエリの言い回しが間違っていますか? 次のクエリは期待どおりの結果を返しますが、洗練されていません。

SELECT ?subject WHERE {
  ?subject example:property ?object1 .
  ?subject example:property ?object2 .
  FILTER(!(?object1=?object2))
}

プロパティ パス クエリは、たとえば、example:property{1,2}またはexample:property{1};を使用すると結果を返します。私が望む結果ではありません。したがって、Jena が構文を正しく解釈していることはわかっていますが、これが古いバージョンの Jena であることもわかっているため、SPARQL 1.1 のすべての機能を認識できない可能性があります。

これは一般的な種類のクエリであり、より洗練されたソリューション (実際にはクックブック ソリューション) が必要だと思います。この問題を解決するためにプロパティ パスを使用するのは正しいですか、それとも別のアプローチを取る必要がありますか? また、プロパティ パスを使用する必要がある場合、それらを正しく使用していますか?

4

1 に答える 1

20

このデータを使用しましょう:

@prefix example: <http://example.org/> .
example:subject1 example:property example:object1 .
example:subject1 example:property example:object2 .

プロパティ パスなし

このようなクエリでは?subjects、 に対して 2 つの異なる値が生成されますexample:property

prefix example: <http://example.org/>
select ?subject where { 
  ?subject example:property ?object1, ?object2 .
  filter ( ?object1 != ?object2 )
}
--------------------
| subject          |
====================
| example:subject1 |
| example:subject1 |
--------------------

ただし、これはほとんどあなたがすでに持っているものです。1 つの結果にまとめるには、次のことができますselect distinct

prefix example: <http://example.org/>
select distinct ?subject where { 
  ?subject example:property ?object1, ?object2 .
  filter ( ?object1 != ?object2 )
}
--------------------
| subject          |
====================
| example:subject1 |
--------------------

プロパティ パスについて

プロパティ パスは、途中ですべての個々のリソースをバインドする必要なく、プロパティのチェーン (順方向および逆方向) を表現する方法です。これは、可変数のエッジを許可する場合に特に重要です。チェーンのどちらかの端にあるものをバインドできますが、中央のものはバインドできません。

データは、グラフィカルに次のようになります。

        example:object1 ← example:property example:subject → example:property example:object2

ある主題に関連する 2 つのオブジェクトを選択する場合は、プロパティ パスを使用できます。example:object1からへのパスは です。これexample:object2(^example:property)/example:propertyexample:propertyエッジを後方example:subjectたどって まで進み、example:propertyエッジを前方にたどって に到達するためexample:object2です。件名ではなくオブジェクトが必要な場合は、次のクエリを使用できます。

prefix example: <http://example.org/>
select * where { 
  ?object1 (^example:property)/example:property ?object2 .
  filter ( ?object1 != ?object2 )
}

プロパティパスを使用してサブジェクトを取得する便利な方法はないと思います。次のようなことができます

?subject property/^property/property/^property ?subject

から?subjectあるオブジェクトに移動し、次に何かに戻ります (つまり、必ずしも?subject、次に再び出てから に戻る?subject必要はありませんが、2 つの異なるオブジェクトが存在するという保証は得られません。

SPARQL プロパティ パスのパス言語は、SPARQL 1.1 クエリ言語勧告 (W3C 標準) のセクション9.1 プロパティ パス構文で説明されています。特に、以前のワーキング ドラフトのセクション 3 パス言語に含まれていた表記は含まれていません。これはあなたのパターンを意味しますp{n}

?subject example:property{2} ?object

実際には合法的な SPARQL ではありません (一部の実装ではサポートされている場合があります)。ただし、作業草案によると、それが何を意味するのかはまだ判断できます。このパターンに一致させるには、次の形式のデータが必要です

        ?subject → example:property [] → example:property ?object

where[]は、任意のリソースを示しているだけです。これは、実際に取得したデータと同じ形状ではありません。したがって、この構文が SPARQL 1.1 で合法であったとしても、探しているタイプの結果は得られません。一般に、プロパティ パスは基本的に、データ内のプロパティ チェーンの一種の正規表現です。

結論

プロパティチェーンは、いくつかのことを非常に素晴らしいものにすることができますが、そうでなければ不可能なことを可能にするものもあります (たとえば、SPARQL の RDF コレクション内の要素の位置を取得することは可能ですか?に対する私の回答を参照してください)。この場合に適しています。あなたの最善の策であり、かなりエレガントな解決策は次のとおりだと思います。

?subject example:property ?object1, ?object2 .
filter( ?object1 != ?object2 ).

?subjectこれは、意図したクエリ「の 2 つの異なる値を持つ を検索する」を最も明確に捉えているためですexample:property。</p>

于 2013-09-20T15:12:48.977 に答える