# To build a social graph

> This protocol supports all graph databases conforming to the RDF specification.

We can have a simple social graph by importing the RDF data constructed from the last chapter.

<figure><img src="https://2101283974-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYeYon1a8IZta2Zm96hF1%2Fuploads%2Fgit-blob-d5ef5305e862945ffd0460281012c6a1c504be94%2Ffollow%20(2).png?alt=media" alt=""><figcaption><p>Figure 7-3 A simple social graph</p></figcaption></figure>

## To use Neptune

> [Amazon Neptune](https://docs.aws.amazon.com/zh_cn/neptune/latest/userguide/intro.html) is a fast and scalable graph database service. It can efficiently store and navigate highly interconnected data. Its query processing engine is optimized for leading graph query languages such as Apache TinkerPop™ Gremlin and W3C's RDF SPARQL. Neptune provides high performance via these open graph frameworks and standard APIs.

With [Amazon Neptune](https://docs.aws.amazon.com/zh_cn/neptune/latest/userguide/intro.html) we can build a social graph using users' behavioral data on the blockchain.

Steps:

1. Launch a Neptune instance via the [aws console](https://ap-northeast-1.console.aws.amazon.com/neptune/home).
2. Composite the sparql constructed from the last chapter into an "insert" command in Neptune:

```sparql
update=PREFIX : <http://relationlabs.ai/entity/>
PREFIX p: <http://relationlabs.ai/property/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
INSERT DATA {GRAPH <http://relationlabs.ai/relationship> {
:Soul_0x0109c8ee3151bde7b6b5d9f37e9d2c4bc16930fe a :Soul;
    p:name "Alice" .
:Soul_0x6247123ec0fe0d25feb811e3c4d4a760c1f2e63e a :Soul;
    p:name "Bob" .
:Soul_0x0109c8ee3151bde7b6b5d9f37e9d2c4bc16930fe p:following :Soul_0x6247123ec0fe0d25feb811e3c4d4a760c1f2e63e .
}}
```

3. Call the Neptune service interface to save RDF:

```shell
curl -X POST --data-binary 'update=PREFIX : <http://relationlabs.ai/entity/>
PREFIX p: <http://relationlabs.ai/property/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
INSERT DATA {GRAPH <http://relationlabs.ai/relationship> {
:Soul_0x0109c8ee3151bde7b6b5d9f37e9d2c4bc16930fe a :Soul;
    p:name "Alice" .
:Soul_0x6247123ec0fe0d25feb811e3c4d4a760c1f2e63e a :Soul;
    p:name "Bob" .
:Soul_0x0109c8ee3151bde7b6b5d9f37e9d2c4bc16930fe p:following :Soul_0x6247123ec0fe0d25feb811e3c4d4a760c1f2e63e .  }}' https://your-neptune-endpoint:port/sparql
```

By now we have indexed the data `Alice follow Bob` into the graph database. We can query the data via the Neptune service interface:

```shell
curl -X POST --data-binary 'query=select * where {
?s a :Soul;
  p:name "Alice".
?s p:following ?f .} limit 10' https://your-neptune-endpoint:port/sparql
```

## To use Jena

For demonstration purposes, we will use [docker](https://www.docker.com/) to launch a Jena service:

```shell
docker run -p 3030:3030 -e ADMIN_PASSWORD=pw123 stain/jena-fuseki
```

If successful, please visit <http://localhost:3030/> using the account "admin" and password "pw123".

1. First please create a dataset:

<figure><img src="https://2101283974-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYeYon1a8IZta2Zm96hF1%2Fuploads%2Fgit-blob-f34b0a811c0d96724dce01071c597ab229d1f8fe%2Fjena-1%20(1).png?alt=media" alt=""><figcaption><p>Figure 7-4 Add a dataset</p></figcaption></figure>

<figure><img src="https://2101283974-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYeYon1a8IZta2Zm96hF1%2Fuploads%2Fgit-blob-048b1c1ce63705392ae5000980f9f428306da76b%2Fjena-2%20(1)%20(2).png?alt=media" alt=""><figcaption><p>Figure 7-5 Create demo dataset</p></figcaption></figure>

2. Then import the data from the last step into the graph database.

```sparql
PREFIX : <http://relationlabs.ai/entity/>
PREFIX p: <http://relationlabs.ai/property/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

:Soul_0x0109c8ee3151bde7b6b5d9f37e9d2c4bc16930fe a :Soul;
    p:name "Alice" .

:Soul_0x6247123ec0fe0d25feb811e3c4d4a760c1f2e63e a :Soul;
    p:name "Bob" .

:Soul_0x0109c8ee3151bde7b6b5d9f37e9d2c4bc16930fe p:following :Soul_0x6247123ec0fe0d25feb811e3c4d4a760c1f2e63e .
```

<figure><img src="https://2101283974-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYeYon1a8IZta2Zm96hF1%2Fuploads%2Fgit-blob-ce8d0ee4b671f69bd0622877afca3d1f9d6afead%2Fjena-3%20(1)%20(2).png?alt=media" alt=""><figcaption><p>Figure 7-6 Upload RDF data</p></figcaption></figure>

<figure><img src="https://2101283974-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYeYon1a8IZta2Zm96hF1%2Fuploads%2Fgit-blob-1065a94c116c037d411a7e055e184996dc523ed8%2Fjena-4%20(1)%20(3).png?alt=media" alt=""><figcaption><p>Figure 7-7 Select a file and upload</p></figcaption></figure>

3. Finally, switch to the Query tag to query which people Alice has followed:

```sparql
PREFIX : <http://relationlabs.ai/entity/>
PREFIX p: <http://relationlabs.ai/property/>

SELECT * WHERE {
  ?me a :Soul;
	p:name "Alice";
    p:following ?following .
  ?following p:name ?name .
}
LIMIT 10
```

<figure><img src="https://2101283974-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYeYon1a8IZta2Zm96hF1%2Fuploads%2Fgit-blob-0ab3237c1463cec391496e3b4a4c2d832497a099%2Fjena-5%20(1)%20(2).png?alt=media" alt=""><figcaption><p>Figure 7-8 Query with SPARQL</p></figcaption></figure>

<figure><img src="https://2101283974-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYeYon1a8IZta2Zm96hF1%2Fuploads%2Fgit-blob-4c87ebf1ac4721a4eeec29c077508901db296015%2Fjena-6%20(1).png?alt=media" alt=""><figcaption><p>Figure 7-9 Query result</p></figcaption></figure>

The query result is : Alice's address `0x0109c8ee3151bde7b6b5d9f37e9d2c4bc16930fe` followed Bob's address `0x6247123ec0fe0d25feb811e3c4d4a760c1f2e63e`.

## To use Neo4j

For demonstration purposes, we will use [docker](https://www.docker.com/) to launch a Neo4j service:

```shell
docker run \
    -p 7474:7474 -p 7687:7687 \
    --name neo4j-neosemantics \
    neo4j:5.5.0
```

1. Install plugins to support RDF

```shell
docker exec -it neo4j-neosemantics bash
cd plugins/
wget https://github.com/neo4j-labs/neosemantics/releases/download/5.5.0.0/neosemantics-5.5.0.0.jar
```

2. Configure Plugin

Open file: `conf/neo4j.conf` and append `dbms.unmanaged_extension_classes=n10s.endpoint=/rdf`.

then restart Neo4j Service:

```shell
docker restart neo4j-neosemantics
```

Open Neo4j Browser: <http://localhost:7474/browser/> Default login is username 'neo4j' and password 'neo4j'.

3. Configure Graph

Execute the following commands in the Neo4j browser input box:

{% tabs %}
{% tab title="cypher-shell" %}

```cypher
CALL n10s.graphconfig.init();

CREATE CONSTRAINT n10s_unique_uri FOR (r:Resource) REQUIRE r.uri IS UNIQUE;

CALL n10s.graphconfig.init( {  handleMultival: "ARRAY" })

CALL n10s.nsprefixes.add("e", "http://relationlabs.ai/entity/");
CALL n10s.nsprefixes.add("p", "http://relationlabs.ai/property/");
```

{% endtab %}
{% endtabs %}

4. Importing RDF Data

Execute the following commands in the Neo4j browser input box:

{% tabs %}
{% tab title="cypher-shell" %}

```cypher
CALL n10s.rdf.import.inline("PREFIX : <http://relationlabs.ai/entity/>
PREFIX p: <http://relationlabs.ai/property/>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

:Soul_0x0109c8ee3151bde7b6b5d9f37e9d2c4bc16930fe a :Soul;
    p:name \"Alice\" .

:Soul_0x6247123ec0fe0d25feb811e3c4d4a760c1f2e63e a :Soul;
    p:name \"Bob\" .

:Soul_0x0109c8ee3151bde7b6b5d9f37e9d2c4bc16930fe p:following :Soul_0x6247123ec0fe0d25feb811e3c4d4a760c1f2e63e .","Turtle");
```

{% endtab %}
{% endtabs %}

5. Querying

Execute the following commands in the Neo4j browser input box:

{% tabs %}
{% tab title="cypher-shell" %}

```cypher
MATCH (ss:Resource {p__name: ["Alice"]})-[:p__following]->(oo) RETURN ss, oo
```

{% endtab %}
{% endtabs %}

<figure><img src="https://2101283974-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYeYon1a8IZta2Zm96hF1%2Fuploads%2Fgit-blob-af6c5c8489b40e97e02751aaf80beb10fd205de4%2Findexer-neo4j.png?alt=media" alt=""><figcaption><p>Figure 7-10 To use Neo4j</p></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://relationlabs.gitbook.io/protocol/indexer/build-graph.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
