フリーランス 技術調査ブログ

フリーランス/エンジニア Ruby Python Nodejs Vuejs React Dockerなどの調査技術調査の備忘録

expressからneo4jにアクセスする

はじめに

neo4j環境を構築できたので、expressからneo4jにアクセスしたいとおもい、その方法を調査していきたいと思います。 px-wing.hatenablog.com

expressのサイトを見るとapocを利用している例があったのでapocで試してみます。 https://expressjs.com/ja/guide/database-integration.html

apocパッケージのインストール

  • インストールすると、下記のようにパッケージの依存関係の警告などが表示される
npm install apoc --save

npm WARN news_backend@1.0.0 No description
npm WARN news_backend@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ apoc@2.1.6
added 23 packages from 23 contributors and audited 501 packages in 6.922s

14 packages are looking for funding
  run `npm fund` for details

found 9 vulnerabilities (2 low, 3 moderate, 3 high, 1 critical)
  run `npm audit fix` to fix them, or `npm audit` for details
  • npm audit fix で実行しても解決できなかったのですが、パッケージの依存関係などは最終的に解決できない場合、パッケージ開発者にissueで修正依頼を出さないとダメそうです。一旦警告を無視して進めます。

脆弱性の警告を受けたnpmパッケージの依存関係を力技で直す - Qiita

利用方法

  • 下記の方法で接続できるようですが、neo4jの接続方法を指定する記述がないことに気づく。
var apoc = require('apoc')

apoc.query('match (n) return n').exec().then(
  function (response) {
    console.log(response)
  },
  function (fail) {
    console.log(fail)
  }
)
  • 接続方法は下記の方法がある

    設定ファイルで接続方法を指定する

  • .apoc.ymlファイルをホームディレクトリに設定する
protocol: http
host: 192.168.0.8
port: 2902
username: neo4j
password: neo4j
  • 下記のエラーが発生し設定ファイルが参照できていないようなエラーとなるため、この方法は一旦保留
Error: getaddrinfo ENOTFOUND undefined
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:64:26) {
  errno: 'ENOTFOUND',
  code: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'undefined'
}

環境変数で指定する

  • 下記の設定をしてみる
export NEO4J_PROTOCOL=http
export NEO4J_HOST=192.168.0.5
export NEO4J_PORT=7474
export NEO4J_USERNAME=neo4j
export NEO4J_PASSWORD=j4neo
  • 接続情報は取得できたようですが、うまく接続できていないようだ。
Chrome/81.0.4044.138 Safari/537.36"
Error: connect EHOSTUNREACH 127.0.1:7474
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
  errno: 'EHOSTUNREACH',
  code: 'EHOSTUNREACH',
  syscall: 'connect',
  address: '127.0.1',
  port: 7474
}

neo4j 公式サイトで利用しているneo4j-driverを推奨してそう

  • neo4j-driverを利用してみる。

https://neo4j.com/developer/javascript/

packageのインストール

npm install neo4j-driver

サンプルソース

  • 下記のサンプルソースを利用する。
  • expressで同期処理を実行する際はasyncの指定を忘れずに。
router.get('/test', async function(req, res){
   const neo4j = require('neo4j-driver')  
   const driver = neo4j.driver('neo4j://<neo4jサーバーのIP>:7687', neo4j.auth.basic('neo4j', 'test'))
   const session = driver.session()
  ## 接続確認する
   try {
     await driver.verifyConnectivity()    
     console.log('Driver created')
   } catch (error) {
     console.log(`connectivity verification failed. ${error}`)
   } 

  ## ノードデータ作成  
   try {
     const result = await session.writeTransaction(tx =>
       tx.run(
         'CREATE (a:Greeting) SET a.message = $message RETURN a.message + ", from node " + id(a)',
         { message: 'hello, world' }
       )
     )
  
    const singleRecord = result.records[0]
    const greeting = singleRecord.get(0)
    console.log(greeting)
    # このconsoleログでは登録したメッセージが表示される
 # (出力結果) hello, world, from node 3
  } finally {
    await session.close()
  }
  
  // on application exit:
  // 自分の場合、この処理はコメントアウトしました。このcloseでTimeoutが発生してしまうため。
  //await driver.close()
  
  // ページを出す。
  res.render("test");
});
  • 接続情報が正しいのにエラーになる
(node:293) UnhandledPromiseRejectionWarning: Error: Unknown scheme: noe4j
    at Object.driver (/src/node_modules/neo4j-driver/lib/index.js:281:13)
    at /src/routes/index.js:12:24
  • 自分の場合、下記のように変更したら接続が成功しましたが、データを登録する処理が失敗していました。<neo4jサーバーのIP>はdocker環境で実装するのであれば、dockerのコンテナ名を指定してください。
  const driver = neo4j.driver('bolt://<neo4jサーバーのIP>:7687', neo4j.auth.basic('neo4j', 'neo4j'))

 JSから直接呼び出しができる(おまけ)

  • CDNでneo4j-driverのJSを呼び出す
<script src="https://unpkg.com/neo4j-driver"></script>
  • 下記の記述でうまく行きました。cdnの時はboltプロトコル出なくても成功しました。
          var driver = neo4j.driver(
            'neo4j://localhost:7687',
            neo4j.auth.basic('neo4j', 'neo4j')
          )
          var session = driver.session()
          session.writeTransaction(tx => tx.run('CREATE (a:Greeting) SET a.message = $message RETURN a.message + ", from node " + id(a)', { message: 'hello, worldTest' }))

実行結果

  • hello worldが3つありますが、GUIから直接作成したものと、express及びJSから1つづノードを登録したので3つ表示されている状態です。 f:id:PX-WING:20200514223128p:plain