> For the complete documentation index, see [llms.txt](https://relationlabs.gitbook.io/protocol/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://relationlabs.gitbook.io/protocol/quick-start/graph-indexer.md).

# Deploying query services using Graph Indexer

Here we will introduce how to quickly build a graph-indexer.

## Prepare the environment

1. Install JDK(Requires JDK11 and above)

{% tabs %}
{% tab title="macOS" %}

```shell
brew install openjdk@11
```

{% endtab %}

{% tab title="CentOS" %}

```shell
sudo yum install java-11-openjdk-devel
```

{% endtab %}
{% endtabs %}

Check the installation:

```shell
java -version
```

2. Install nodejs

To complete this tutorial successfully, you must have [Node.js](https://nodejs.org/en/) installed on your machine.

* Install Node.js with [NVM](https://github.com/nvm-sh/nvm)

## Install jena-fuseki

Install and run:

```shell
wget  https://dlcdn.apache.org/jena/binaries/apache-jena-fuseki-4.7.0.tar.gz
tar xvf apache-jena-fuseki-4.7.0.tar.gz
cd apache-jena-fuseki-4.7.0
sh fuseki-server
```

## Create a dataset

You can access <http://localhost:3030>, and create a demo dataset(Figure 1-1, Figure 1-2)

<figure><img src="/files/WefVWoBBGi4oziU8SpzT" alt=""><figcaption><p>Figure 1-1 Add a dataset</p></figcaption></figure>

<figure><img src="/files/eDiSFgZHvsNCPqbTJIIZ" alt=""><figcaption><p>Figure 1-2 Create demo dataset</p></figcaption></figure>

## A simple Graph Indexer

Here, we will use Node.js to accomplish this process.

> This example will listen to RDF data on the Mumbai network, between blocks 32362681 and 32362699.

1. Create a new project and install the `ethers (v5)`, `axios`, and `qs`.

```shell
mkdir graph-indexer
cd graph-indexer
npm init -y
npm install ethers@5 axios qs
```

2. Create an `app.js` file with the following content:

```javascript
const axios = require('axios')
const qs = require('qs')
const ethers = require('ethers')
const rpc = 'https://polygon-mumbai.blockpi.network/v1/rpc/public'
let abi = ['event CreateRDF(uint256 indexed tokenId, string rdfStatements)']
const provider = new ethers.providers.JsonRpcProvider(rpc)
const iface = new ethers.utils.Interface(abi)
const filter = {}

// Listen to all new events on the blockchain.
provider.on(filter, async (e) => {
  try {
    let event = iface.parseLog(e)
    if (event) {
      const rdf = event.args[1]
        // todo: Do your own business
      const res = await insertRdf(rdf)
    }
  } catch (error) {}
})

// You can also get the data of the specified filter
const logFilter = {
  fromBlock: 32362681,
  toBlock: 32362699
}
provider
  .getLogs(logFilter)
  .then(function (logs) {
    for (let index = 0; index < logs.length; index++) {
      try {
        const log = logs[index]
        const event = iface.parseLog(log)
        if (event) {
          const rdf = event.args[1]
          insertRdf(rdf)
        }
      } catch (error) {}
    }
  })
  .catch(function (err) {
    console.log(err)
  })

// Insert RDF into Graph database.
function insertRdf(rdfString) {
  const data = qs.stringify({
    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  {
      ${rdfString}
    }`
  })
  const config = {
    method: 'post',
    maxBodyLength: Infinity,
    url: 'http://localhost:3030/demo/update',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    data: data
  }

  return axios(config)
    .then(function (response) {
      console.log(JSON.stringify(response.data))
    })
    .catch(function (error) {
      console.log(error)
    })
}
```

3. Run the Graph Indexer

```shell
node app.js
```

After the data has been inserted, it can be queried at <http://localhost:3030/#/dataset/demo/query>.

<figure><img src="/files/4wwAuxVT61rR3d80nboO" alt=""><figcaption><p>Figure 1-3 Query results using SPARQL</p></figcaption></figure>
