首页 > 解决方案 > VDS.RDF.GraphHandler 用于跳过三元组

问题描述

我只想解析 ~100 MB rdf cell line ontology中的一些数据。到目前为止,我对 1.387.097 个三元组中的 169.796 个感兴趣(跳过了 1.217.301 个三元组)。

我需要大约 24 秒的时间使用下面的处理程序来创建图表。这仅比解析本体少几秒钟。

跳过我不感兴趣的元组有什么可以改进的吗?

谢谢!

private class MyHandler : VDS.RDF.GraphHandler
    {
        public MyHandler(IGraph g)
            : base(g)
        {
        }

        protected override bool HandleTripleInternal(Triple t)
        {
            if (t.Predicate is UriNode uri 
                && uri.Uri.AbsoluteUri != "http://www.w3.org/2000/01/rdf-schema#subClassOf"
                && uri.Uri.AbsoluteUri != "http://www.w3.org/2000/01/rdf-schema#label")
            {
                return true;
            }
            else if (t.Object is LiteralNode l && l.Language == "zh")
            {
                return true;
            }
            return base.HandleTripleInternal(t);
        }
    }

标签: c#dotnetrdf

解决方案


为了使节点的比较更快一点,您可以尝试直接与UriNode从图中创建的节点进行比较,而不是比较 URI 字符串。如果您IGraph.CreateUriNode()在过滤器构造函数中使用该方法创建节点rdfs:subClassOfrdfs:label然后IUriNode.Equals()用作比较器,那么您应该会发现节点比较可以使用更快的对象引用相等而不是字符串比较。

private class MyHandler : GraphHandler
{
    private readonly IUriNode _rdfsSubClassOf;
    private readonly IUriNode _rdfsLabel;

    public MyHandler(IGraph g)
        : base(g)
    {
        _rdfsSubClassOf = g.CreateUriNode(UriFactory.Create("http://www.w3.org/2000/01/rdf-schema#subClassOf"));
        _rdfsLabel = g.CreateUriNode(UriFactory.Create("http://www.w3.org/2000/01/rdf-schema#label"));
    }

    protected override bool HandleTripleInternal(Triple t)
    {
        if (t.Predicate is UriNode uri
            && !uri.Equals(_rdfsSubClassOf)
            && !uri.Equals(_rdfsLabel))
        {
            return true;
        }
        else if (t.Object is LiteralNode l && l.Language == "zh")
        {
            return true;
        }
        return base.HandleTripleInternal(t);
    }
}

但是,这只会加快过滤器的速度,我怀疑如果您分析文件的解析,您会发现大部分时间都花在解析语法以创建传递给过滤器的三元组。在 dotNetRDF 处理程序架构中并没有真正解决此问题的方法。


推荐阅读