Joel Bender
Joel Bender

Reputation: 23

Visual Graph showing blank nodes

Ontotext GraphDB 9.0.0, Free Edition, Ubuntu Workstation Linux 4.15.0-65-generic x86_64

I have a graph that contains blank nodes:

@prefix : <urn:ex:> .

:Dave :hasFather [ :name "John" ] .

When I look at the Explore/Graphs Overview for the default graph, both triples are displayed and the subject :Dave has a father _:node3. However, the object is displayed as text rather than a resource link like :Dave. When I select :Dave there is one row (as expected), and when I select Visual graph is says "this node has no visible connections."

Under Explore/Visual Graph/Easy Graph attempting to search for _:node3 says that it is an invalid URI.

How can I navigate visually through a graph with blank nodes?

Upvotes: 1

Views: 991

Answers (2)

AtesComp
AtesComp

Reputation: 451

To fully construct a visualization, you need to create a custom "Graph expansion" query like so:

# Note that ?node is the node you clicked and must be used in the query
PREFIX rank: <http://www.ontotext.com/owlim/RDFRank#>
PREFIX ent: <http://www.ontotext.com/owlim/entity#>

CONSTRUCT
{
    # The triples that will be added to the visual graph
    ?newNodeLX  ?edge  ?newNodeRX .
}
WHERE
{
  {
    {
        # Left to right relations (starting IRI is the subject)
        ?node ?edge ?newNodeR .
        # ?node is always an IRI, ?newNodeR must be checked for IRI or Blank
        FILTER(isIRI(?newNodeR) || isBlank(?newNodeR))
        BIND(IF(isBlank(?newNodeR), URI(CONCAT("BNode:", STR(ent:id(?newNodeR)))), ?newNodeR) AS ?newNodeRX)
        BIND(?node AS ?newNodeLX)
    }
    UNION
    {
        # Right to left relations (starting IRI is the object)
        ?newNodeL ?edge ?node .
        # ?node is always an IRI, ?newNodeL is always an IRI or Blank
        BIND(IF(isBlank(?newNodeL), URI(CONCAT("BNode:", STR(ent:id(?newNodeL)))), ?newNodeL) AS ?newNodeLX)
        BIND(?node AS ?newNodeRX)
    }
  }
  UNION
  {
    {
        # Left to right relations (starting Blank is the subject)
        ?nodeC ?edge ?newNodeR .
        # ?nodeC must be checked for Blank, ?newNodeR must be checked for IRI or Blank
        FILTER(isBlank(?nodeC))
        FILTER(isIRI(?newNodeR) || isBlank(?newNodeR))
        BIND(IF(isBlank(?newNodeR), URI(CONCAT("BNode:", STR(ent:id(?newNodeR)))), ?newNodeR) AS ?newNodeRX)
        BIND(URI(CONCAT("BNode:", STR(ent:id(?nodeC)))) AS ?newNodeLX)
        FILTER(?newNodeLX = ?node)
    }
    UNION
    {
        # Right to left relations (starting Blank is the object)
        ?newNodeL ?edge ?nodeC .
        # ?nodeC must be checked for Blank, ?newNodeL is always an IRI or Blank
        FILTER(isBlank(?nodeC))
        BIND(IF(isBlank(?newNodeL), URI(CONCAT("BNode:", STR(ent:id(?newNodeL)))), ?newNodeL) AS ?newNodeLX)
        BIND(URI(CONCAT("BNode:", STR(ent:id(?nodeC)))) AS ?newNodeRX)
        FILTER(?newNodeRX = ?node)
    }
  }
}
#ORDER BY ?edge

and augment it with a "Node basics" query like so:

# Note that ?node is the relevant node's IRI and must be used in the query
PREFIX sesame: <http://www.openrdf.org/schema/sesame#>
PREFIX ent: <http://www.ontotext.com/owlim/entity#>

SELECT ?type {
  {
    # Get node direct type
    ?node sesame:directType ?type.
  }
  UNION
  {
    # Get node direct type
    ?nodeB sesame:directType ?type.
    FILTER(isBlank(?nodeB) && URI(CONCAT("BNode:", STR(ent:id(?nodeB)))) = ?node)
  }
} ORDER BY ?type

and a "Node extra" query like so:

# Note that ?node is the node you clicked and must be used in the query
PREFIX ent: <http://www.ontotext.com/owlim/entity#>

SELECT ?property ?value {
  {
    # Gets all datatype properties (?property) with literals as values (?value)
    ?node ?property ?value .
    # Select only literals
    FILTER(isLiteral(?value))
  }
  UNION
  {
    ?nodeB ?property ?value .
    FILTER(isLiteral(?value))
    FILTER(isBlank(?nodeB) && URI(CONCAT("BNode:", STR(ent:id(?nodeB)))) = ?node)
  }
}

Upvotes: 1

Desislava Hristova
Desislava Hristova

Reputation: 84

GraphDB Visual Graph shows only IRIs. Blank nodes doesn't give any information to the user. Why are you using a blank node for the father? I find this inconsistent with the fact that :Dave is IRI. I suggest you update your data to:


:Dave :hasFather :Jonh  .

If you still want keep the bnodes, you can modify the query for visualization. Execute a Construct query in the SPARQL editor:

CONSTRUCT { 
    :Dave :hasFather ?fatherIRI
} WHERE {
    :Dave :hasFather ?bnode.
    ?bnode :name ?nameLiteral.
    BIND( IRI(CONCAT("http://test", ?nameLiteral)) as ?fatherIRI)
}

and click the "Visual" button. This will create a virtual IRI for your bnode that can be displayed visually. Also, if this approach works for you, you can create a custom visual graph. See "Create custom graph view over your RDF data" in GraphDB documentation.

Upvotes: 1

Related Questions