LoginSignup
4
5

More than 5 years have passed since last update.

Neo4j tutorial 作業記録

Last updated at Posted at 2018-10-26

Windows10 に Neo4j を入れて tutorial を実行する

グラフデータベースに少し興味があったのでインストールして動かす
RDBMS の言葉を混ぜつつ自分が理解するための作業記録
私がそもそも NoSQL について初心者なので、NoSQL の概要くらいは知ってることが前提

ぶっちゃけこの方の記事を見たほうが早いですな
https://qiita.com/tikamoto/items/c3a1bba12e9b83aee42a

インストール

Neo4j 公式サイトよりダウンロード https://neo4j.com/
Desktopではなく、Community Server(Neo4j Community Edition 3.4.9 for windows)
D:\neo4j にインストールした

DB起動

インストールした場所の readme.txt を読むと


1. Open a console and navigate to the install directory.
2. Start the server:
   Windows, use: bin\neo4j console
   Linux/Mac, use: ./bin/neo4j console
3. In a browser, open http://localhost:7474/
4. From any REST client or browser, open http://localhost:7474/db/data
   in order to get a REST starting point, e.g.
   curl -v http://localhost:7474/db/data
5. Shutdown the server by typing Ctrl-C in the console.

ということなのでコマンドプロンプトで d:\neo4j\bin\neo4j console で起動する
起動メッセージが出るのでコマンドプロンプトはそのまま
Ctrl+C を押すとDB停止になる

ブラウザでアクセス

readme.txt にあるようにブラウザで http://localhost:7474/ にアクセス
UserName / Password は neo4j / neo4j

ブラウザからできること

・Learn about Neo4j : Neo4j の説明
・Jump into code : 実際にデータを追加検索して後始末までを確認できる
・Monitor the system : システム情報
・一番上の入力欄で DML や DSL を入力実行するとその下に結果が表示される
(SQL に相当する Cypher という言語で Neo4j を制御する)


実際に jump into code をやってみる

The Movie Graph という tutorial のシナリオは、映画を題材に監督、役者、プロデューサー等の情報をデータベースにしたもの

テーブル作成&データ入れ(Create)

・映画の情報作成


CREATE (YouveGotMail:Movie {title:"You've Got Mail", released:1998, tagline:'At odds in life... in love on-line.'})

YouveGotMail という映画用の Movie Node を作成。 title 属性 "You've Got Mail"、他に released, tagline, の属性を付加

・役者の情報の作成


CREATE (TomH:Person {name:'Tom Hanks', born:1956})

TomH という役者用 Person Node を作成。name 属性 に Tom Hanks, Born 属性に 1956 を付加

・映画と役者の関連付け


CREATE (TomH)-[:ACTED_IN {roles:['Joe Fox']}]->(YouveGotMail)

TomH は 'Joe Fox' 役(roles)で YouveGotMail に出演

ただの検索(Find)

・名前が Tom Hanks のデータを表示


MATCH (q1 {name: "Tom Hanks"}) RETURN q1

解説:name が Tom Hanks であるデータ(この場合 Person Node にしか name 属性はない) を検索し q1 という変数に格納。q1 の値を返す

・title が "Cloud Atlas" であるデータ(この場合 Movie Node) を返せ


MATCH (q2 {title: "Cloud Atlas"}) RETURN q2

・Person Node から name を 10 人返せ


MATCH (people:Person) RETURN people.name LIMIT 10

・90年代にリリースされた映画のタイトルを表示しろ


MATCH (nineties:Movie) WHERE nineties.released >= 1990 AND nineties.released < 2000 RETURN nineties.title

関連付け検索(Query)

・Tom Hanks が出演した映画を全て表示


MATCH (tom:Person {name: "Tom Hanks"})-[:ACTED_IN]->(tomHanksMovies) RETURN tom,tomHanksMovies

解説:tom:Person {name: "Tom Hanks"}でTom Hanks を限定し tom 変数に格納。tom に ACTED_IN で関連付けされた映画を tomHanksMovies に格納し、tom と tomHanksMovies を RETURN している。

・映画 Cloud Atlas の監督を全員表示


MATCH (cloudAtlas {title: "Cloud Atlas"})<-[:DIRECTED]-(directors) RETURN directors.name

上もそうだけど、-> や <- のところがちょっと不明。結合と解釈するとちょっと怪しいのでマニュアル参照。後で修正。Cypher の書き方がよくわからないけど、これがグラフデータベースの特徴かな。

・Tom Hanks の相手役を表示


MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors) RETURN coActors.name

上と同じく関連付での表示

・Cloud Atlas に関係した人を表示(Type で属性を表示)


MATCH (people:Person)-[relatedTo]-(:Movie {title: "Cloud Atlas"}) RETURN people.name, Type(relatedTo), relatedTo

経路検索(Solve)

・Kevin Bacon を中心として1階層~4階層まで関連付けていって重複削除して表示


MATCH (bacon:Person {name:"Kevin Bacon"})-[*1..4]-(hollywood)
RETURN DISTINCT hollywood

1..4 のところの 4 を 小さくしたり大きくしたりすると関連付けの深さが変わる
1..1 なら映画が 3 つ表示されるだけ
1..2 なら映画 3 つとその関連の人が表示される
1..4 多すぎ

たぶんこっちのほうがわかりやすい
Kevin Baconが出演した映画とその関連者(3つの映画とその映画の監督や役者が出る)


MATCH (bacon:Person {name:"Kevin Bacon"})-[*1..2]-(hollywood)
RETURN DISTINCT bacon,hollywood

・最短経路検索 Kevin Bacon から Meg Ryan への関連付けを辿った時の最短の関連付け


MATCH p=shortestPath(
  (bacon:Person {name:"Kevin Bacon"})-[*]-(meg:Person {name:"Meg Ryan"})
)
RETURN p

レコメンド(Recommend)

・Tom Hanks と仕事をしたことない人を表示


MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors),
      (coActors)-[:ACTED_IN]->(m2)<-[:ACTED_IN]-(cocoActors)
WHERE NOT (tom)-[:ACTED_IN]->()<-[:ACTED_IN]-(cocoActors) AND tom <> cocoActors
RETURN cocoActors.name AS Recommended, count(*) AS Strength ORDER BY Strength DESC

・Tom Hanks と仕事をしたことがない Tom Cruise を誰が Tom Hanks に紹介したらいいかを問い合わせ


MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors),
      (coActors)-[:ACTED_IN]->(m2)<-[:ACTED_IN]-(cruise:Person {name:"Tom Cruise"})
RETURN tom, m, coActors, m2, cruise

データのお片付け(Clean Up)

・全部の node を消す前にMATCH (n) RETURN nで確認
・Person と Movie のノードを消す(実行したら上のコードを実行すると全部消えてることが確認できる)

MATCH (n) DETACH DELETE n

DB停止

起動したコマンドプロンプトで Ctrl+C を押すとDBが停止する

最後に

以上で、Getting Started みたいなものの一部が終了

もう一つ RDBMS から Neo4j への移行のtutorialがある
それは別の記事にしようかと思ったけど、面倒なのでこのまま

tutorial その2 RDBMS to Neo4j

tutorial の2つ目はどうやら RDBMS から Neo4j への移行するとどうなるかを確認できるらしい
面倒なので色々端折る

RDBMSのデータ(CSV)を読み込み Node 作成

・ネットにあるファイルをダウンロードして読み込む

LOAD CSV WITH HEADERS FROM "http://data.neo4j.com/northwind/products.csv" AS row

これで、ネットから CSV をダウンロードしてきて変数 row に打ち込めるらしい
WITH HEADERS をつけるとそれがそのまま属性になるっぽい

・上でロードしたデータを使って Product Node の作成(ついでにデータ型の整形)


CREATE (n:Product)
SET n = row,
  n.unitPrice = toFloat(row.unitPrice),
  n.unitsInStock = toInteger(row.unitsInStock),
 n.unitsOnOrder = toInteger(row.unitsOnOrder),
  n.reorderLevel = toInteger(row.reorderLevel),
 n.discontinued = (row.discontinued <> "0")

整形せずに入れるだけなら SET n = row だけでいい

・次に進む前に入れたデータを確認してみる

MATCH(n) RETURN n

上でロードした node が全部 Relation なしで存在していることがわかる

リレーションをはる(関連付ける)

・Category に Product を関連付ける


MATCH (p:Product),(c:Category)
WHERE p.categoryID = c.categoryID
CREATE (p)-[:PART_OF]->(c)

注意:you only need to compare property values like this when first creating relationships
(関連付けは上記のようなプロパティの比較だけでいい)
実行した後 MATCH(n) RETURN n すると Category に Product が PART_OF で関連づいているのがわかる

・Product に Supplier を関連付ける


MATCH (p:Product),(s:Supplier)
WHERE p.supplierID = s.supplierID
CREATE (s)-[:SUPPLIES]->(p)

実行した後 MATCH(n) RETURN n すると Product に Supplier が SUPPLIES で関連づいているのがわかる

問い合わせ

・Supplier 毎に、何の製品カテゴリを扱っているかを表示


MATCH (s:Supplier)-->(:Product)-->(c:Category)
RETURN s.companyName as Company, collect(distinct c.categoryName) as Categories

・Produce 業(category)をしている会社(Supplier)を表示


MATCH (c:Category {categoryName:"Produce"})<--(:Product)<--(s:Supplier)
RETURN DISTINCT s.companyName as ProduceSuppliers

顧客情報と関連付けて表示

・顧客情報を読み込んで node 作成やら index 作成やら関連付けやらを実行
・製品情報と顧客情報とを絡め、顧客毎に produce 業への注文数を集計して多い順に表示


MATCH (cust:Customer)-[:PURCHASED]->(:Order)-[o:ORDERS]->(p:Product),
      (p)-[:PART_OF]->(c:Category {categoryName:"Produce"})
RETURN DISTINCT cust.contactName as CustomerName, SUM(o.quantity) AS TotalProductsPurchased
ORDER BY TotalProductsPurchased DESC

以上

4
5
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
4
5