LoginSignup
6
10

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-01-07

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を打てばグラフが作成されているはずです.

以上です!

6
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
10