1

このグラフを見てください:

:thing1 a :Foo ;
    :has :A ;
    :has :B .

:thing2 a :Foo ;
    :has :B ;
    :has :A .

:thing3 a :Foo ;
    :has :A ;
    :has :B ;
    :has :C .

:thing1と を選択したいのですが:thing2、 ではありません :thing3

これが私が書いた SPARQL クエリです。これを行うより良い方法はありますか?

SELECT ?foo WHERE {
    ?foo a :Foo ;
        :has :A ;
        :has :B .
    MINUS {
        ?foo a :Foo ;
            :has :A ;
            :has :B ;
            :has ?anythingElse .
        FILTER(?anythingElse != :A && ?anythingElse != :B)
    }
}
4

2 に答える 2

3

MINUS の代替は FILTER NOT EXISTS です。

SELECT ?foo WHERE {
    ?foo a :Foo ;
        :has :A, :B .
   FILTER NOT EXISTS {
       ?foo :has ?other .
       FILTER (?other NOT IN (:A, :B))
    }
}

大まかに言うと、:A と :B を持つすべての ?foo を見つけて、他の :has 値がないことを確認します。

実行効率の観点から、一部の MINUS パターンを FILTER NOT EXISTS に、またはその逆に変換する最適化があり、共通のサブパターンを共有する可能性もあります。

オプティマイザーがそれほど賢くなければ、「?foo a :Foo ; ;has :A, :B 」のため、FILTER NOT EXISTS の方が高速になる可能性があります。は繰り返されず、FILTER は既に "?foo a :Foo ; ;has :A, :B ." を通過したアイテムのみを考慮します。

キャッシングを含むすべての効果が一緒になったときに、実際のデータで実際に試してみることです。

于 2015-03-16T09:47:00.807 に答える
0

ブール式の代わりに演算子を使用してこれを行うことができます。実際、節を節にNOT IN置き換えれば、3 つのトリプル パターンを繰り返す必要はありません。MINUSFILTER NOT EXISTS

SELECT ?foo WHERE {
    ?foo a :Foo ;
        :has :A, :B .
    FILTER NOT EXISTS {
       ?foo :has ?other .
       FILTER (?other NOT IN (:A, :B))
    }
}

パフォーマンスに大きな違いがあるとは思えませんが、クエリは短くなり、読みやすくなっています。

于 2015-03-15T23:06:08.827 に答える