TL;DR
PSO2のギャザリングを題材にNeo4jの使い方を練習してみたので勘所を書いておく。
ざっくり言うと、素材から料理を作って、料理で素材取得などのブーストを掛けるシステム。
RDBだと辛そうだけどグラフDBなら見通し良さそうなので試した。
Node
粒度
- RDBで検索の主キーに使うものは片っ端からノードにすると楽な印象。
- ノードは「ラベル」という大分類を持つので、種別ごとに整理できる。
- 今回は4種類のラベルを作った(Category, Dish, Fish, Pick)
種類ごとのノード作成例
- Dish (料理)
create (dish:Dish {name:"森林トマトのサラダ"})
create (dish:Dish {name:"森林アユのトマト煮"})
※Webインターフェースを使って入力する場合、createは1行ごとに実行すること。
- Category
create (category:Category {name:"野菜"})
create (category:Category {name:"大型"})
create (category:Category {name:"魚類"})
create (category:Category {name:"小型"})
- Pick (採取)
create (pick:Pick {name:"森林トマト"})
- Fish (釣り)
※ゲーム内の扱いは「採取」で採れるものと同格。採るときにタイミング判定がある程度。なので同じ感じで用意しておく。
create (pick:Fish {name:"森林アユ"})
ここまでで出来るグラフ
MATCH (n) RETURN n LIMIT 25
Relationship
RelationshipにはPropertyを設定できる。
料理(Dish)と材料(Pick,Fish)
ひとまず「USE」として紐付けする。
材料ごとに使う個数を設定する。
- 材料1種類の場合
match (dish:Dish {name:"森林トマトのサラダ"}),(pick:Pick {name:"森林トマト"})
merge (dish)-[roles:USE{number:10}]->(pick)
return dish,pick
- 材料2種類の場合
match (dish:Dish {name:"森林アユのトマト煮"}),(pick:Pick {name:"森林トマト"}),(fish:Fish {name:"森林アユ"})
merge (dish)-[roles1:USE{number:10}]->(pick)
merge (dish)-[roles2:USE{number:10}]->(fish)
return dish,pick,fish
relationshipの仮引数の名称さえ分ければ何個でも書ける。
材料(Pick,Fish)と種類(Category)
- 森林トマト
「野菜」で「大型」
match (pick:Pick {name:"森林トマト"}),(category1:Category {name:"野菜"}),(category2:Category {name:"大型"})
merge (pick)-[belong1:BELONG]->(category1)
merge (pick)-[belong2:BELONG]->(category2)
return pick,category1,category2
- 森林アユ
「魚類」で「小型」
match (fish:Fish {name:"森林アユ"}),(category1:Category {name:"魚類"}),(category2:Category {name:"小型"})
merge (fish)-[belong1:BELONG]->(category1)
merge (fish)-[belong2:BELONG]->(category2)
return fish,category1,category2
料理(Dish)と種類(Category)
料理を食べると採取や釣りなどの材料に種類別ブーストが掛かる。
ブーストの効果時間や、追加効果をどう処理するかは未定なので今回は記載しない。でも恐らくノードにすると見やすそう。
- 森林トマトのサラダ
match (dish:Dish {name:"森林トマトのサラダ"}),(category:Category {name:"野菜"})
merge (dish)-[boost:BOOST]->(category)
return dish,boost
- 森林アユのトマト煮
match (dish:Dish {name:"森林アユのトマト煮"}),(category:Category {name:"大型"})
merge (dish)-[boost:BOOST]->(category)
return dish,boost
まとめて表示
MATCH ()-[r]->() RETURN r LIMIT 25
Wikiだとテーブル表現になってしまうので有機的な繋がりが見えないが、グラフDBならこんなに見やすくなる。
参考文献
Cypher Query Language(QL)-初級編 #neo4j https://www.creationline.com/lab/7685
PSO2ギャザリング(swiki) http://pso2.swiki.jp/index.php?%E3%82%AE%E3%83%A3%E3%82%B6%E3%83%AA%E3%83%B3%E3%82%B0#u614ae64
Relationship with Properties with Existing Nodes https://www.tutorialspoint.com/neo4j/neo4j_create_relationship_with_properties_with_existing_nodes.htm
is there a way to add multiple nodes with properties in Neo4j with Cypher https://stackoverflow.com/questions/21605388/is-there-a-way-to-add-multiple-nodes-with-properties-in-neo4j-with-cypher