基于谓词节点检索特定RDF图三元组

时间:2013-07-31 10:16:55

标签: rdf dotnetrdf

我正在使用 dotnetrdf 发送Sparql CONSTRUCT查询并评估结果IGraph

首先,我试图找到代表给定类型个体的所有Uri节点,比如说,

http://www.example.com/InterestingThing

所以,我想使用GetTriplesWithPredicateObject method,将http://www.w3.org/1999/02/22-rdf-syntax-ns#type作为谓词并将http://www.example.com/InterestingThing作为对象传递。该方法需要两个对象实现INode interface,因此我尝试使用图形GetUriNode method找到相应的节点。

问题:未找到谓词。

在查看调试器中的IGraph对象时,似乎GetUriNode只能找到图中Nodes enumeration中包含的内容 - 而且只包含有的Uri节点被用作主语或对象,但没有被用作谓词。

现在,谓词Uri节点显然在那里 - 我可以在浏览图形的Triples object时看到它们。它们出现在可以直接从该对象检索的Triple instances中,也可以在同一对象的PredicateNodes property中找到它们。

有趣的是,IGraph的某些查询方法(例如GetTriplesWithObjectGetTriplesWithPredicate)确实有超载,只接受Uri而不是INode - 但{ {3}}没有。

现在,各种可行的解决方法显而易见:

  • 使用只占GetTriplesWithPredicate个实例的Uri重载,然后手动过滤生成的三元组。
  • 手动搜索所有三元组以获得所需的三元组。
  • 手动搜索PredicateNodes列表,找到搜索到Uris的内容。

所有这些似乎都是不必要的麻烦 - 因为现有的方法建议乍一看,人们应该只能使用GetUriNode来检索两个节点然后将它们传递给一个节点现成的查询方法,例如GetTriplesWithObjectPredicate

因此,我的问题是:

我在dotnetrdf库中或在概念上,在RDF中遗漏了什么,或者这种行为是否会因设计对开发人员造成障碍?

这是一个重现问题的C#测试用例(查询DBpedia):

using System;
using System.Collections.Generic;
using System.Linq;

using VDS.RDF;
using VDS.RDF.Query;

namespace Test
{
    class Program
    {
        public static void Main(string[] args)
        {
            // Querying
            // All entries to analyze are declared to belong to a temporary type, and
            // two properties are mapped to temporary property identifiers.

            Console.WriteLine();

            var endpoint = new SparqlRemoteEndpoint(new Uri("http://dbpedia.org/sparql"));

            string query = "PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>\n"
                + "PREFIX ex: <http://www.example.com/>\n"
                + "\n"
                + "CONSTRUCT {\n"
                + "  ?r a ex:record.\n"
                + "  ?r ex:prop1 ?v1.\n"
                + "  ?r ex:prop2 ?v2.\n"
                + "}\n"
                + "WHERE {\n"
                + "  {\n"
                + "    SELECT ?r\n"
                + "    WHERE {\n"
                + "      ?r a dbpedia-owl:Work.\n"
                + "      FILTER(EXISTS { ?r dbpedia-owl:originalLanguage [] } && EXISTS { ?r dbpedia-owl:author/dbpedia-owl:birthPlace [] }).\n"
                + "    } LIMIT 5\n"
                + "  }\n"
                + "  ?r dbpedia-owl:originalLanguage ?v1.\n"
                + "  ?r dbpedia-owl:author/dbpedia-owl:birthPlace ?v2.\n"
                + "}";

            Console.WriteLine(query);
            Console.WriteLine();

            IGraph graph = endpoint.QueryWithResultGraph(query);

            PrintNodes("IGraph.Nodes", graph.Nodes);

            Console.WriteLine("All triples from IGraph.Triples:");
            foreach (var triple in graph.Triples) {
                Console.WriteLine("- S: " + NodeToString(triple.Subject));
                Console.WriteLine("  P: " + NodeToString(triple.Predicate));
                Console.WriteLine("  O: " + NodeToString(triple.Object));
            }
            Console.WriteLine();

            PrintNodes("IGraph.Triples.SubjectNodes", graph.Triples.SubjectNodes);
            PrintNodes("IGraph.Triples.PredicateNodes", graph.Triples.PredicateNodes);
            PrintNodes("IGraph.Triples.ObjectNodes", graph.Triples.ObjectNodes);

            // Graph Analysis
            // The following code tries to retrieve exactly the items of the temporary
            // type "record".

            var typeNode = TryFindUriNode(graph, new Uri(NamespaceMapper.RDF + "type"));
            var recordNode = TryFindUriNode(graph, new Uri("http://www.example.com/record"));

            Console.WriteLine();
            TryFindAllNodes("subjects", graph, graph.Triples.SubjectNodes.OfType<IUriNode>().Select(node => node.Uri));
            TryFindAllNodes("predicates", graph, graph.Triples.PredicateNodes.OfType<IUriNode>().Select(node => node.Uri));
            TryFindAllNodes("objects", graph, graph.Triples.ObjectNodes.OfType<IUriNode>().Select(node => node.Uri));
            Console.WriteLine();

            var createdTypeNode = graph.CreateUriNode(new Uri(NamespaceMapper.RDF + "type"));
            var createdRecordNode = graph.CreateUriNode(new Uri("http://www.example.com/record"));

            if ((typeNode != null) && (recordNode != null)) {
                Console.WriteLine("{0} triple(s) with found predicate and found object.",
                                  graph.GetTriplesWithPredicateObject(typeNode, recordNode).Count());
            }
            if (typeNode != null) {
                Console.WriteLine("{0} triple(s) with found predicate and created object.",
                                  graph.GetTriplesWithPredicateObject(typeNode, createdRecordNode).Count());
            }
            if (recordNode != null) {
                Console.WriteLine("{0} triple(s) with created predicate and found object.",
                                  graph.GetTriplesWithPredicateObject(createdTypeNode, recordNode).Count());
            }
            Console.WriteLine("{0} triple(s) with created predicate and created object.",
                              graph.GetTriplesWithPredicateObject(createdTypeNode, createdRecordNode).Count());
        }

        private static string NodeToString(INode node)
        {
            return string.Format("{0} ({1})", node, node.GetType().Name);
        }

        private static void PrintNodes(string title, IEnumerable<INode> nodes)
        {
            Console.WriteLine(title + ":");
            foreach (var node in nodes) {
                Console.WriteLine("- " + NodeToString(node));
            }
            Console.WriteLine();
        }

        private static INode TryFindUriNode(IGraph graph, Uri uri)
        {
            var result = graph.GetUriNode(uri);
            if (result == null) {
                Console.WriteLine(uri.ToString() + " was NOT found by IGraph.GetUriNode.");
            } else {
                Console.WriteLine(uri.ToString() + " WAS found by IGraph.GetUriNode.");
            }
            return result;
        }

        private static void TryFindAllNodes(string title, IGraph graph, IEnumerable<Uri> uris)
        {
            Console.WriteLine("Trying to find all " + title + ":");
            foreach (Uri uri in uris) {
                TryFindUriNode(graph, uri);
            }
        }
    }
}

这是示例程序的输出:

PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX ex: <http://www.example.com/>

CONSTRUCT {
  ?r a ex:record.
  ?r ex:prop1 ?v1.
  ?r ex:prop2 ?v2.
}
WHERE {
  {
    SELECT ?r
    WHERE {
      ?r a dbpedia-owl:Work.
      FILTER(EXISTS { ?r dbpedia-owl:originalLanguage [] } && EXISTS { ?r dbpedia-owl:author/dbpedia-owl:birthPlace [] }).
    } LIMIT 5
  }
  ?r dbpedia-owl:originalLanguage ?v1.
  ?r dbpedia-owl:author/dbpedia-owl:birthPlace ?v2.
}

IGraph.Nodes:
- http://dbpedia.org/resource/Electra_(Sophocles) (UriNode)
- http://dbpedia.org/resource/Peer_Gynt (UriNode)
- http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
- http://dbpedia.org/resource/The_Field (UriNode)
- http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
- http://www.example.com/record (UriNode)
- http://dbpedia.org/resource/Ancient_Greek (UriNode)
- http://dbpedia.org/resource/Colonus (UriNode)
- http://dbpedia.org/resource/Norwegian_language (UriNode)
- http://dbpedia.org/resource/Skien (UriNode)
- http://dbpedia.org/resource/Norway (UriNode)
- http://dbpedia.org/resource/Czech_language (UriNode)
- http://dbpedia.org/resource/Kingdom_of_Bohemia (UriNode)
- http://dbpedia.org/resource/Bohemia (UriNode)
- http://dbpedia.org/resource/Mal%C3%A9_Svato%C5%88ovice (UriNode)
- http://dbpedia.org/resource/Austria-Hungary (UriNode)
- http://dbpedia.org/resource/English_language (UriNode)
- http://dbpedia.org/resource/Irish_Free_State (UriNode)
- http://dbpedia.org/resource/Listowel (UriNode)
- http://dbpedia.org/resource/County_Kerry (UriNode)

All triples from IGraph.Triples:
- S: http://dbpedia.org/resource/Electra_(Sophocles) (UriNode)
  P: http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
  O: http://www.example.com/record (UriNode)
- S: http://dbpedia.org/resource/Electra_(Sophocles) (UriNode)
  P: http://www.example.com/prop1 (UriNode)
  O: http://dbpedia.org/resource/Ancient_Greek (UriNode)
- S: http://dbpedia.org/resource/Electra_(Sophocles) (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Colonus (UriNode)
- S: http://dbpedia.org/resource/Peer_Gynt (UriNode)
  P: http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
  O: http://www.example.com/record (UriNode)
- S: http://dbpedia.org/resource/Peer_Gynt (UriNode)
  P: http://www.example.com/prop1 (UriNode)
  O: http://dbpedia.org/resource/Norwegian_language (UriNode)
- S: http://dbpedia.org/resource/Peer_Gynt (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Skien (UriNode)
- S: http://dbpedia.org/resource/Peer_Gynt (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Norway (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
  P: http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
  O: http://www.example.com/record (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
  P: http://www.example.com/prop1 (UriNode)
  O: http://dbpedia.org/resource/Czech_language (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Kingdom_of_Bohemia (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Bohemia (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Mal%C3%A9_Svato%C5%88ovice (UriNode)
- S: http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Austria-Hungary (UriNode)
- S: http://dbpedia.org/resource/The_Field (UriNode)
  P: http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
  O: http://www.example.com/record (UriNode)
- S: http://dbpedia.org/resource/The_Field (UriNode)
  P: http://www.example.com/prop1 (UriNode)
  O: http://dbpedia.org/resource/English_language (UriNode)
- S: http://dbpedia.org/resource/The_Field (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Irish_Free_State (UriNode)
- S: http://dbpedia.org/resource/The_Field (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Listowel (UriNode)
- S: http://dbpedia.org/resource/The_Field (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/County_Kerry (UriNode)
- S: http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
  P: http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
  O: http://www.example.com/record (UriNode)
- S: http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
  P: http://www.example.com/prop1 (UriNode)
  O: http://dbpedia.org/resource/Norwegian_language (UriNode)
- S: http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Skien (UriNode)
- S: http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)
  P: http://www.example.com/prop2 (UriNode)
  O: http://dbpedia.org/resource/Norway (UriNode)

IGraph.Triples.SubjectNodes:
- http://dbpedia.org/resource/Electra_(Sophocles) (UriNode)
- http://dbpedia.org/resource/Peer_Gynt (UriNode)
- http://dbpedia.org/resource/Pictures_from_the_Insects'_Life (UriNode)
- http://dbpedia.org/resource/The_Field (UriNode)
- http://dbpedia.org/resource/The_Lady_from_the_Sea (UriNode)

IGraph.Triples.PredicateNodes:
- http://www.w3.org/1999/02/22-rdf-syntax-ns#type (UriNode)
- http://www.example.com/prop1 (UriNode)
- http://www.example.com/prop2 (UriNode)

IGraph.Triples.ObjectNodes:
- http://www.example.com/record (UriNode)
- http://dbpedia.org/resource/Ancient_Greek (UriNode)
- http://dbpedia.org/resource/Colonus (UriNode)
- http://dbpedia.org/resource/Norwegian_language (UriNode)
- http://dbpedia.org/resource/Skien (UriNode)
- http://dbpedia.org/resource/Norway (UriNode)
- http://dbpedia.org/resource/Czech_language (UriNode)
- http://dbpedia.org/resource/Kingdom_of_Bohemia (UriNode)
- http://dbpedia.org/resource/Bohemia (UriNode)
- http://dbpedia.org/resource/Mal%C3%A9_Svato%C5%88ovice (UriNode)
- http://dbpedia.org/resource/Austria-Hungary (UriNode)
- http://dbpedia.org/resource/English_language (UriNode)
- http://dbpedia.org/resource/Irish_Free_State (UriNode)
- http://dbpedia.org/resource/Listowel (UriNode)
- http://dbpedia.org/resource/County_Kerry (UriNode)

Trying to find all subjects:
http://dbpedia.org/resource/Electra_(Sophocles) WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Peer_Gynt WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Pictures_from_the_Insects'_Life WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/The_Field WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/The_Lady_from_the_Sea WAS found by IGraph.GetUriNode.
Trying to find all predicates:
http://www.w3.org/1999/02/22-rdf-syntax-ns#type was NOT found by IGraph.GetUriNode.
http://www.example.com/prop1 was NOT found by IGraph.GetUriNode.
http://www.example.com/prop2 was NOT found by IGraph.GetUriNode.
Trying to find all objects:
http://www.example.com/record WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Ancient_Greek WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Colonus WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Norwegian_language WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Skien WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Norway WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Czech_language WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Kingdom_of_Bohemia WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Bohemia WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Mal‚_Svatonovice WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Austria-Hungary WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/English_language WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Irish_Free_State WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/Listowel WAS found by IGraph.GetUriNode.
http://dbpedia.org/resource/County_Kerry WAS found by IGraph.GetUriNode.

http://www.w3.org/1999/02/22-rdf-syntax-ns#type was NOT found by IGraph.GetUriNode.
http://www.example.com/record WAS found by IGraph.GetUriNode.
5 triple(s) with created predicate and found object.
5 triple(s) with created predicate and created object.

可以看出,IGraph.Nodes枚举包含谓词Uris,例如http://www.example.com/prop1http://www.w3.org/1999/02/22-rdf-syntax-ns#type。同样,输出显示GetUriNode找不到谓词,而主题和对象则是。

2 个答案:

答案 0 :(得分:2)

您可以使用CreateURINode中的INodeFactoryIGraph扩展名)来创建rdf:type节点,并具有以下内容:

graph.GetTriplesWithPredicateObject(
  graph.CreateUriNode( UriFactory.createUri( "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" )), ,
  graph.CreateUriNode( UriFactory.createUri( "http://www.example.com/InterestingThing" ))
)

这类似于我在耶拿采用的方法,我使用ResourceFactory.createProperty( http://...ns#type )之类的方法。 (实际上,Jena有一个常数RDF.type以方便我使用,但这是我用于未被提前定义为常量的方法。)

答案 1 :(得分:2)

这种行为完全是设计的,只出现在谓词位置的东西被认为是图中的边缘,而不是图中的节点。

由于Working with Graphs文档声明如下:

  

要选择节点,可以使用可用于查找节点的方法   来自图表(如果存在),这是GetXNode()方法,其中X   是要检索的节点的类型。请注意,此方法仅适用   如果给定值作为图中的节点存在,则返回一个值,即   它出现在此图中三元组的主题/对象位置。

     

注意:如果您只想获取其他用法的Node实例   无论它是否已存在于您应该使用的图表中   取而代之的是CreateXNode()方法。

也许GetEdge()和相应的Edges属性会有用吗?

相关问题