基于谓词节点检索特定的 RDF 图三元组 [英] Retrieving Specific RDF Graph Triples Based on Predicate Nodes

查看:66
本文介绍了基于谓词节点检索特定的 RDF 图三元组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using dotnetrdf to send a Sparql CONSTRUCT query and evaluate the resulting IGraph.

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

For a start, I am trying to find all Uri nodes that represent individuals of a given type, say,

http://www.example.com/InterestingThing

所以,我想使用 GetTriplesWithPredicateObject 方法,传递 http://www.w3.org/1999/02/22-rdf-syntax-ns#type 作为谓词和 http://www.example.com/InterestingThing 作为一个对象.该方法需要两个对象实现 INode 接口,所以我试图用图表的 GetUriNode 方法.

So, I would like to use the GetTriplesWithPredicateObject method, passing http://www.w3.org/1999/02/22-rdf-syntax-ns#type as a predicate and http://www.example.com/InterestingThing as an object. That method expects two objects implementing the INode interface, so I am trying to find the respective nodes with the graph's GetUriNode method.

在调试器中查看 IGraph 对象时,似乎 GetUriNode 只能找到 Nodes 枚举 - 并且只包含已经被用作主语或宾语,但不用作谓语.

When looking at the IGraph object in the debugger, it seems that GetUriNode can find only what is contained in the Nodes enumeration of the graph - and that contains only Uri nodes that have been used as subjects or objects, but none that are used as predicates.

现在,谓词 Uri 节点显然在那里 - 我可以在探索 图形的Triples 对象.它们出现在 Triple 实例中可以直接从该对象中检索,它们也可以在 PredicateNodes 属性.

Now, the predicate Uri nodes are evidently there - I can see them when exploring the Triples object of the graph. They appear in the Triple instances that can be retrieved directly from that object, and they can also be found in the PredicateNodes property of the same object.

有趣的是,IGraph 的一些查询方法如GetTriplesWithObjectGetTriplesWithPredicate 确实有只接受 Uri 而不是 INode - 但 GetTriplesWithPredicateObject 没有.

Interestingly, some querying methods of IGraph such as GetTriplesWithObject or GetTriplesWithPredicate do have overloads that accept a mere Uri instead of an INode - but GetTriplesWithPredicateObject does not.

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

Now, various possible workarounds are obvious:

  • 使用仅接受 Uri 实例的 GetTriplesWithPredicate 重载,然后手动过滤生成的三元组.
  • 手动搜索所有三元组以获得所需的三元组.
  • 手动搜索 PredicateNodes 列表并找到具有搜索到的 Uris 的那些.
  • Use the overload of GetTriplesWithPredicate that takes only a Uri instance, then filter the resulting triples manually.
  • Manually search through all triples to get the desired triples.
  • Manually search through the list of PredicateNodes and find the ones with the searched for Uris.

所有这些似乎都不必要地繁琐 - 正如现有方法建议乍一看应该能够简单地使用 GetUriNode 来检索两个节点,然后通过这些到现成的查询方法之一,例如 GetTriplesWithObjectPredicate.

All of these seem unnecessarily cumbersome, though - as the existing methods suggest at first glance that one should simply be able to use GetUriNode to retrieve two nodes and then pass those to one of the ready-made querying methods such as GetTriplesWithObjectPredicate.

因此,我的问题是:

我是否遗漏了 dotnetrdf 库或 RDF 概念中的任何内容,或者这种行为是否在设计上给开发人员带来了障碍?

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

Here is a C# test case to reproduce the problem (querying 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 没有找到谓词,而主语和宾语却找到了.

As can be seen, the IGraph.Nodes enumeration does not include the predicate Uris such as http://www.example.com/prop1 or http://www.w3.org/1999/02/22-rdf-syntax-ns#type. Likewise, the output shows that predicates are not found by GetUriNode, while subjects and objects are.

推荐答案

您可以使用 CreateURINode 来自 INodeFactory (IGraph 扩展)来创建 rdf:type 节点,并具有类似:

You can use CreateURINode from INodeFactory (which IGraph extends) to create the rdf:type node, and have something like:

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" ))
)

这类似于我在 Jena 中采用的方法,在那里我会使用诸如 ResourceFactory.createProperty( http://...ns#type ) 之类的东西.(实际上,Jena 有一个常量 RDF.type 为了方便我会使用,但这是我用于未提前定义为常量的方法.)

This is similar to the approach I'd take in Jena, where I'd use something like ResourceFactory.createProperty( http://...ns#type ). (Actually, Jena has a constant RDF.type for convenience that I'd use, but this is the approach I'd use for one that wasn't defined as a constant ahead of time.)

这篇关于基于谓词节点检索特定的 RDF 图三元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆