2

私は、哲学者に影響を与えた哲学者を示す次の DBpedia SPARQL を持っています。ただし、哲学者が複数の を持っている場合は重複を返しますfoaf:name

SELECT ?name ?influencedName
  WHERE {
  ?philosopher a dbpedia-owl:Philosopher ;
    dbpedia-owl:influenced ?influenced ;
    foaf:name ?name .
  ?influenced  a dbpedia-owl:Philosopher ;
    foaf:name ?influencedName .
}

SPARQL の結果

?nameとに複数の値がある場合、単一の名前を返すにはどうすればよいですか?includedName。最初の 1 つ、または保持する文字を選択する最小数に満足します。

これは、プラトンがバートランド・ラッセルに影響を与えた別の例です。これで1行を返したいのですが、4つになります:

SELECT ?name ?influencedName
  WHERE {
  ?philosopher a dbpedia-owl:Philosopher ;
    dbpedia-owl:influenced ?influenced ;
    foaf:name ?name , "Plato"@en .
  ?influenced  a dbpedia-owl:Philosopher ;
    foaf:name ?influencedName, "Bertrand Arthur William Russell, 3rd Earl Russell"@en .
}

SPARQL の結果

4

2 に答える 2

3

クエリ

次のようなクエリが必要なようです。

SELECT ?philosopher ?pName ?influence (SAMPLE(?iName) as ?iName)
WHERE {
  # This subquery selects all the philosophers and
  # selects just one of their names . 
  {
    SELECT ?philosopher (SAMPLE(?pName) as ?pName) WHERE {
      ?philosopher a dbpedia-owl:Philosopher ;
                   foaf:name ?pName .
    }
    GROUP BY ?philosopher
  }

  # This main query selects the influence of the 
  # philosophers and select their names.  The GROUP
  # BY on the outer query puts all the
  # (?philosopher,?pName,?influence,?iName) tuples 
  # that have the same ?philosopher, ?pName, and 
  # influence together, and the (SAMPLE(?iName) as ?iName)
  # in the outer SELECT combines them all, choosing an 
  # arbitrary representative ?iName.
  ?influence dbpedia-owl:influenced ?philosopher ;
             a dbpedia-owl:Philosopher ;
             foaf:name ?iName .
}
GROUP BY ?philosopher ?pName ?influence

SPARQL の結果

名前だけに興味があり、実際のリソースを選択することを気にしない場合は、必要なく?philosopher?influence最も外側SELECTにあり、それを作成できます

SELECT ?pName (SAMPLE(?iName) as ?iName)
WHERE { …

SPARQL の結果

ORDER BY結果を確認しやすくするために、最後にを追加することもできます。

…
GROUP BY ?philosopher ?pName ?influence
ORDER BY ?pName

SPARQL の結果

Plato の場合、これらの最後の結果には次の行が含まれます。

"Plato"@en  "Socrates"@en
"Plato"@en  "Parmenides"@en
"Plato"@en  "Zeno of Elea"@en
"Plato"@en  "Pythagoras"@en
"Plato"@en  "Gorgias"@en
"Plato"@en  "Protagoras"@en
"Plato"@en  "Heraclitus"@en

ここに書いたクエリでは、哲学者の s のSAMPLE1 つを任意に選択していましたが、値を選択するために使用できる 集約代数foaf:nameには他の関数があります。順番に「最初の」値が必要な場合は、Minに興味があるかもしれません。

サブクエリ、GROUP BY、SAMPLE、MIN など

これは、実際には、SPARQL 仕様のセクション 12、サブクエリでサブクエリについて示した例と非常によく似ています。その例では、次のクエリを使用して、Alice が知っている人を選択し、それぞれについて、人の名前を 1 つだけ選択します。

PREFIX : <http://people.example/>
SELECT ?y ?minName
WHERE {
  :alice :knows ?y .
  {
    SELECT ?y (MIN(?name) AS ?minName)
    WHERE {
      ?y :name ?name .
    } GROUP BY ?y
  }
}

これは、哲学的影響力の問題に適応するのはそれほど難しくありませんでした。哲学者の問題は、すべての哲学者とその名前を選択し、実際の哲学者リソースでグループ化し、サンプルを使用して各哲学者の代表的な名前を選ぶことから始まりました。外側のクエリも同じことを行いますが、哲学者を選択するのではなく、各哲学者に影響を与えたエンティティを選択しています。結果はグループ化され、影響の代表的な名前が選択されます。

于 2013-06-16T01:23:34.050 に答える
1

哲学者の一意の名前を選択する方法を決定しました。哲学者ごとに 1 つの名前を返す以下の sparql を参照してください。

ただし、哲学者と影響を受けた哲学者の両方の名前を返す大きなクエリにこれを組み込む理由はわかりません。哲学者ごとにこのコードを一度実行すると、大きくて扱いにくいクエリになります。私の感覚では、哲学者の名前と影響を受けたクエリを別々に実行し、sparql ではなくコードで名前を検索すると、コードが読みやすくなるということです。おそらく、これを簡単にするいくつかの sparql 機能が欠けています。ご意見をお聞かせください

一意の名前を取得する方法の説明は次のとおりです。

foaf:names および dbprop:names から Philosopher のすべての名前を取得する 少なくとも 1 つのラテン文字 ( AZ ) を含む名前のみを含めるようにフィルター処理する 最も短い名前の長さを見つける 最も短いすべての名前の中で最小のものを選択する

PREFIX dbpedia: <http://dbpedia.org/>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dbpprop: <http://dbpedia.org/property/>

SELECT ?philosopher (min(?name) as ?minName)
WHERE {{
   ?philosopher foaf:name ?name        .
  } UNION {
   ?philosopher dbpprop:name ?name     .
  }
  FILTER( strlen(?name) = ?minLength )   .  # get the shortest names
  FILTER( REGEX( str(?name) , "[A-Z]" )) .  # exlude names with no latin charachters
  {
    SELECT ?philosopher (min(strlen(?name)) as ?minLength)
    WHERE {{
      ?philosopher a  dbpedia-owl:Philosopher ;
         foaf:name ?name .
    } UNION {
      ?philosopher a  dbpedia-owl:Philosopher ;
         dbpprop:name ?name .
    }
    FILTER( REGEX( str(?name) , "[A-Z]" )) .
    }
    GROUP BY ?philosopher
  }
}
GROUP BY ?philosopher
ORDER BY ?philosopher
于 2013-06-16T16:52:31.157 に答える