

# Using RDF data
Using RDF data

 Neptune Analytics supports importing RDF data using the n-triples format. The handling of RDF values is described below, including how RDF data is interpreted as LPG concepts and can be queried using openCypher. 

## Handling of RDF values


 The handling of RDF specific values, that don‘t have a direct equivalent in LPG, is described here. 

### IRIs


 Values of type IRI, like `<http://example.com/Alice>` , are stored as such. IRIs and Strings are distinct data types. 

 Calling openCypher function `TOSTRING()` on an IRI returns a string containing the IRI wrapped inside `<>`. For example, if `x` is the IRI `<http://example.com/Alice>`, then `TOSTRING(x)` returns `"<http://example.com/Alice>"`. When serializing openCypher query results in json format, IRI values are included as strings in this same format. 

### Language-tagged literals


 Values like `"Hallo"@de` are treated as follows: 
+  When used as input for openCypher string functions, like `trim()`, a language-tagged string is treated as a simple string; so `trim("Hallo"@de)` is equivalent to `trim("Hallo")`. 
+  When used in comparison operations, like `x = y` or `x <> y` or `x < y` or `ORDER BY`, a language-tagged literal is “greater than” (and thus “not equal to”) the corresponding simple string: `"Hallo" < "Hallo"@de`. 

 Calling a function, such as `TOSTRING()` on a language-tagged literal, returns that literal as a string without language tag. For example, if `x` is the value `"Hallo"@de`, then `TOSTRING(x)` returns `"Hallo"`. When serializing openCypher query results in JSON format, language-tagged literals are also serialized as strings without an associated language tag. 

### Blank nodes


 Blank nodes in n-triples data files are replaced with globally unique IRIs at import time. 

 Loading RDF datasets that contains blank nodes is supported; but those blank nodes are represented as IRIs in the graph. When loading ntriples files the parameter `blankNodeHandling` needs to be specified, with the value `convertToIri`. 

 The generated IRI for a blank node has the format: `<http://aws.amazon.com/neptune/vocab/v01/BNode/scope#id>` 

 In these IRIs, `scope` is a unique identifier for the blank node scope, and `id` is the blank node identifier in the file. For example for a blank node `_:b123` the generated IRI could be `<http://aws.amazon.com/neptune/vocab/v01/BNode/737c0b5386448f78#b123>`. 

 The **blank node scope** (e.g. 737c0b5386448f78) is generated by Neptune Analytics and designates one file within one load operation. This means that when two different ntriples files reference the same blank node identifier, like `_:b123`, there will be two IRIs generated, namely one for each file. All references to `_:b123` within the first file will end up as references to the first IRI, like `<http://aws.amazon.com/neptune/vocab/v01/BNode/1001#b123>`, and all references within the second file will end up referring to another IRI, like `<http://aws.amazon.com/neptune/vocab/v01/BNode/1002#b123>`. 

# Referencing IRIs in queries


 There are two ways to reference an IRI in an openCypher query: 
+  Wrap the full IRI inside `<` and `>` . Depending on where in the query this IRI is referenced, the IRI is then provided as a String, such as `"<http://example.com/Alice>"` (when the IRI is the value of property `~id`), or in backticks such as ``<http://example.com/Alice>`` (when the IRI is a label, or property key). 

  ```
  CREATE (:`<http://xmlns.com/foaf/0.1/Person>` {`~id`: "<http://example.com/Alice>"})
  ```
+  Define a PREFIX at the start of the query, and inside the query reference an IRI using `prefix::suffix`. For example, after `PREFIX ex: <http://example.com/>` the reference `ex::Alice` also references the full IRI `<http://example.com/Alice>`. 

  ```
  PREFIX foaf: <http://xmlns.com/foaf/0.1/>
  PREFIX ex: <http://example.com/>
  CREATE (: foaf::Person {`~id`: ex::Alice})
  ```

 Additional query examples below show the use of both full IRIs and the prefix syntax. 

# Mapping RDF triples to LPG concepts


 There are three rules that define how RDF triples correspond to LPG concepts: 

```
Case     RDF triple                   ⇆    LPG concept
-----------------------------------------------------------------
Case #1  { <iri> rdf:type <iri> }     ⇆    vertex with id + label
Case #2  { <iri> <iri> "literal"}     ⇆    vertex property
Case #3  { <iri> <iri> <iri> }        ⇆    edge with label
```

**Case \$11: Vertex with id and label**

 A triple like: 

```
<http://example.com/Alice> rdf:type <http://xmlns.com/foaf/0.1/Person>
```

 is equivalent to creating the vertex in openCypher like: 

```
CREATE (:`<http://xmlns.com/foaf/0.1/Person>` {`~id`: "<http://example.com/Alice>"})
```

 In this example, the vertex label `<http://xmlns.com/foaf/0.1/Person>` is interpreted and stored as an IRI. 

**Note**  
 The back quote syntax ```` is part of openCypher which allows inserting characters that normally cannot be used in labels. Using this mechanism, it’s possible to include complete IRIs in a query. 

 Using `PREFIX`, the same `CREATE` query could look like: 

```
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.com/>
CREATE (: foaf::Person {`~id`: ex::Alice})
```

 To match the newly created vertex based on its id: 

```
MATCH (v {`~id`: "<http://example.com/Alice>"}) RETURN v
```

 or equivalently: 

```
PREFIX ex: <http://example.com/>
MATCH (v {`~id`: ex::Alice}) RETURN v
```

 To find vertices with that RDF Class/LPG Label: 

```
MATCH (v:`<http://xmlns.com/foaf/0.1/Person>`) RETURN v
```

 or equivalently: 

```
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
MATCH (v : foaf::Person) RETURN v
```

**Case \$12: Vertex property**

 A triple like: 

```
<http://example.com/Alice> <http://xmlns.com/foaf/0.1/name> "Alice Smith"
```

 is equivalent to defining with openCypher node with a given `~id` and property, where both the `~id` and the property key are IRIs: 

```
CREATE ({`~id`: "<http://example.com/Alice>",
        `<http://xmlns.com/foaf/0.1/name>`: "Alice Smith" })
```

 or equivalently: 

```
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.com/>
CREATE ({`~id`: ex::Alice, foaf::name: "Alice Smith" })
```

 To match the vertex with that property: 

```
MATCH (v {`<http://xmlns.com/foaf/0.1/name>`: "Alice Smith"}) RETURN v
```

 or equivalently: 

```
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
MATCH (v { foaf::name : "Alice Smith"}) RETURN v
```

**Case \$13: Edge**

 A triple like: 

```
<http://example.com/Alice> <http://example.com/knows> <http://example.com/Bob>
```

 is equivalent to defining with OpenCypher an edge like this, where the edge label and vertices ids are all IRIs: 

```
CREATE ({`~id`: "<http://example.com/Alice>"})
          -[:`<http://example.com/knows>`]->({`~id`: "<http://example.com/Bob>"})
```

 or equivalently: 

```
PREFIX ex: <http://example.com/>
CREATE ({`~id`: ex::Alice })-[: ex::knows ]->({`~id`: ex::Bob })
```

 To match the edges with that label: 

```
MATCH (v)-[:`<http://example.com/knows>`]->(w) RETURN v, w
```

 or equivalently: 

```
PREFIX ex: <http://example.com/>
MATCH (v)-[: ex::knows ]->(w) RETURN v, w
```

## Query Examples


**Matching language-tagged literals**

 If this triple was loaded from a dataset: 

```
<http://example.com/German> <http://example.com/greeting> "Hallo"@de
```

 then it will **not** be matched by this query: 

```
MATCH (n) WHERE n.`<http://example.com/greeting>` = "Hallo"
```

 because the language-tagged literal `"Hallo"@de` and the string “Hallo” are not equal. For more information, see [Language-tagged literals](using-rdf-data.md#rdf-handling-language-tagged-literals). The query can use `TOSTRING()` in order to find the match: 

```
MATCH (n) WHERE TOSTRING(n.`<http://example.com/greeting>`) = "Hallo"
```