scalaからneo4jを扱ってみる(embedded or restAPI)

  • 8
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

scalaのプログラムからneo4jを扱ってみます.
今回はサンプルとしてscalaからneo4jでノードをcreateするところをやりたいと思います.

そして,扱う方法としては,neo4jを組み込む方法かrestAPIで操作する方法がありますのでどちらも書きます.

今回はPlay!2.4を使ってやってみました.
(Playを使う必然性は全然ありません..)
いくつかコードがでてきますが,前提としてはすでにactivatorでプロジェクトを作っていることとします.

コードについて詳しくは書いていないのでHow Toみたいな感じになってしまいました.

build.sbtの追加部分はplayを使っても使わなくても同じだし,app/MatrixContorllercreate関数の中の処理もさほど変わらない思います!

雛形

conf/routes

conf/routes
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~

GET     /create                     controllers.MatrixController.create

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)

http://localhost:9000/create でノードを作成することにします.

app/MatrixController.scala

app/MatrixController.scala
package controllers

import play.api._
import play.api.mvc._


class MatrixController extends Controller {

  def create  = Action{
    //ここに処理書いていくってことで
    Ok(<p>Inserted nodes and rels</p>).as(HTML)
  }

}

embedded

restAPIで操作するより,組み込んだ方が処理速度が10倍くらい速いっていうのをどっかのサイトで見た気がします.

ここからは実際にコードを書いていきます.

build.sbt

build.sbt
name := """neo4j_play"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.6"

libraryDependencies ++= Seq(
  jdbc,
  cache,
  ws,
  specs2 % Test,
  // 以下を追加
  "org.neo4j" % "neo4j" % "2.3.0"
)

resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"

// Play provides two styles of routers, one expects its actions to be injected, the
// other, legacy style, accesses its actions statically.
routesGenerator := InjectedRoutesGenerator

libraryDependenciesにneo4jのライブラリを追加しました.

app/MatrixController.scala

app/MatrixController.scala
package controllers

import play.api._
import play.api.mvc._
//以下を追加
import org.neo4j.cypher.ExecutionEngine
import org.neo4j.graphdb.GraphDatabaseService
import org.neo4j.graphdb.factory.GraphDatabaseFactory


class MatrixController extends Controller {

  def create  = Action{
    val db: GraphDatabaseService = new GraphDatabaseFactory().newEmbeddedDatabase("neo4j/matrix")
    val engine: ExecutionEngine = new ExecutionEngine(db)

    val cypher = Array(
    val cypher = Array(
    """
    |CREATE
    |      (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'}),
    |      (Keanu:Person {name:'Keanu Reeves', born:1964}),
    |      (Carrie:Person {name:'Carrie-Anne Moss', born:1967}),
    |      (Laurence:Person {name:'Laurence Fishburne', born:1961}),
    |      (Hugo:Person {name:'Hugo Weaving', born:1960}),
    |      (AndyW:Person {name:'Andy Wachowski', born:1967}),
    |      (LanaW:Person {name:'Lana Wachowski', born:1965}),
    |      (JoelS:Person {name:'Joel Silver', born:1952}),
    |      (Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix),
    |      (Carrie)-[:ACTED_IN {roles:['Trinity']}]->(TheMatrix),
    |      (Laurence)-[:ACTED_IN {roles:['Morpheus']}]->(TheMatrix),
    |      (Hugo)-[:ACTED_IN {roles:['Agent Smith']}]->(TheMatrix),
    |      (AndyW)-[:DIRECTED]->(TheMatrix),
    |      (LanaW)-[:DIRECTED]->(TheMatrix),
    |      (JoelS)-[:PRODUCED]->(TheMatrix)
  """.stripMargin
  )

    val ns = Stream.from(1).iterator
    cypher.foreach { c =>
      println(s"command${ns.next} :")
      println(engine.execute(c).dumpToString())
    }
    db.shutdown()
    Ok(<p>Inserted nodes and rels</p>).as(HTML)
  }

}

この処理のコードは[Neo4J]  ⑥ 組み込みサーバーモードでCypherを実行の記事を参考にさせていただきました.

著者さんがサンプルコードをgithubにあげていたのでリンクから飛んでみるといいと思います.

あとはactivator runとか打って/createのURLを打てば/neo4j/matrixにdbが作成されていて,グラフが作成されているかと思います.

restAPI

scalaからneo4jをrestAPIで扱うライブラリとしてAnormCypherがあります.

ここで注意して欲しいことが1つ.
先ほどの組み込みではneo4j2.3を使っていましたが,AnormCypherではサポートされていないのでバージョンを下げてください.
(組み込みでも2.3である必要はないので適宜バージョンを変更してください)

Integration tests currently run against neo4j-community-2.1.3.

build.sbt

build.sbt
name := """neo4j_play"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.6"

libraryDependencies ++= Seq(
  jdbc,
  cache,
  ws,
  specs2 % Test,
  //以下を追加
  "org.anormcypher" %% "anormcypher" % "0.7.1"
)

resolvers ++= Seq(
  "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases",
  //以下を追加
  "anormcypher" at "http://repo.anormcypher.org/",
  "Typesafe Releases" at "http://repo.typesafe.com/typesafe/releases/"
)

// Play provides two styles of routers, one expects its actions to be injected, the
// other, legacy style, accesses its actions statically.
routesGenerator := InjectedRoutesGenerator

app/MatrixController.scala

app/MatrixController.scala
package controllers

import play.api._
import play.api.mvc._
import org.anormcypher.{Neo4jREST, Cypher}
import play.api.libs.ws.ning


class MatrixController extends Controller {

  def create  = Action{
    implicit val wsclient = ning.NingWSClient()
    implicit val connection = Neo4jREST()(wsclient)
    implicit val ec = scala.concurrent.ExecutionContext.global
    Cypher(
      """
      CREATE
      (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'}),
      (Keanu:Person {name:'Keanu Reeves', born:1964}),
      (Carrie:Person {name:'Carrie-Anne Moss', born:1967}),
      (Laurence:Person {name:'Laurence Fishburne', born:1961}),
      (Hugo:Person {name:'Hugo Weaving', born:1960}),
      (AndyW:Person {name:'Andy Wachowski', born:1967}),
      (LanaW:Person {name:'Lana Wachowski', born:1965}),
      (JoelS:Person {name:'Joel Silver', born:1952}),
      (Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix),
      (Carrie)-[:ACTED_IN {roles:['Trinity']}]->(TheMatrix),
      (Laurence)-[:ACTED_IN {roles:['Morpheus']}]->(TheMatrix),
      (Hugo)-[:ACTED_IN {roles:['Agent Smith']}]->(TheMatrix),
      (AndyW)-[:DIRECTED]->(TheMatrix),
      (LanaW)-[:DIRECTED]->(TheMatrix),
      (JoelS)-[:PRODUCED]->(TheMatrix)
      """
    ).execute()
    wsclient.close()
    Ok(<p>Inserted nodes and rels</p>).as(HTML)
  }

}

実行

今回はすでに起動しているneo4jにクエリを投げるので,予めdbを作成し,起動しておいてください!

あとは先程と同様に実行してからurlを打てばグラフが作成されているはずです.

以上です!