# 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>


---

# 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/quick-start/graph-indexer.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.
