# 使用Graph Indexer部署Social Graph的查询服务

这里将介绍如何快速构建一个 graph-indexer。

## 环境依赖

1. 安装 jdk(要求 JDK11 及以上)

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

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

{% endtab %}

{% tab title="CentOS" %}

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

{% endtab %}
{% endtabs %}

安装完成后检查

```shell
java -version
```

2. 安装 nodejs

开始本教程之前，您的计算机上必须安装[Node.js](https://nodejs.org/en/)。

* 使用[NVM](https://github.com/nvm-sh/nvm)安装 Node.js。

## 安装 jena-fuseki

安装 jena-fuseki 并运行：

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

## 创建数据集

浏览器访问 <http://localhost:3030>，并创建 demo 数据集（图 1-1、图 1-2）

<figure><img src="https://3668324987-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdqevFF76s9Kq7JWAPlD3%2Fuploads%2Fgit-blob-df5d9e9620a3106d7f7f9f49293d59f5c685fc94%2Fgraph-indexer-quick-start-jena1%20(1)%20(1)%20(4).png?alt=media" alt=""><figcaption><p>图 1-1 添加数据集</p></figcaption></figure>

<figure><img src="https://3668324987-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdqevFF76s9Kq7JWAPlD3%2Fuploads%2Fgit-blob-a125587ddf95c88bea644ca702ee0f7eef21777e%2Fgraph-indexer-quick-start-jena2%20(1)%20(1)%20(5).png?alt=media" alt=""><figcaption><p>图 1-2 创建demo数据集</p></figcaption></figure>

## 一个简单的 Graph Indexer

这里我们使用 nodejs 来完成。

> 本示例将会监听Mumbai网络上32362681至32362699区块的RDF数据。

1. 新建一个项目，安装 `ethers(v5)`、`axios`、`qs` 库

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

2. 监听链上数据，创建一个 app.js，内容如下：

```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 = {}

// 监听链上所有新的事件
provider.on(filter, async (e) => {
  try {
    let event = iface.parseLog(e)
    if (event) {
      const rdf = event.args[1]
        // todo: 做自己的业务逻辑
      const res = await insertRdf(rdf)
    }
  } catch (error) {}
})

// 也可以获取指定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)
  })

// 将rdf插入数据库
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. 运行 Graph Indexer 程序

```shell
node app.js
```

等待数据插入后，即可在<http://localhost:3030/#/dataset/demo/query>中查询到

<figure><img src="https://3668324987-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdqevFF76s9Kq7JWAPlD3%2Fuploads%2Fgit-blob-9022db156a34e0dabf53ddb13dc30db30f93b806%2Fgraph-indexer-quick-start-jena3.png?alt=media" alt=""><figcaption><p>图 1-3 使用SPARQL查询索引结果</p></figcaption></figure>
