RedisGraphでアイマスのGraphを作ってみる
はじめに
RedisGraphどころかRedisすら触ったことなかったけど、QuickStartのクエリを見様見真似でやったのでそこまで詳しくないです。
でも、RedisGraphの日本語記事が無かったんで試しに使ってみた。みたいな記事です。
RedisGraphとは
公式サイトにあるPrimary featuresを見ていきましょう。
- Property Graph Modelに基づいてる。
たぶんこんな感じの、ノードとノードの間に意味を持つエッジ(ブランチ)があるグラフのことでしょう。
- ノードとエッジは属性を持つこともできる。
im@sparqlのように、あらゆる事象をエッジとノードで表すのではなく、
このように、ノードにある程度の情報を持たせても良いらしい。
im@sparql(RDF)では名前の文字列を与えるにしてもエッジを用意していたので、これは結構助かるかも?でも、属性にするか、別ノードにするかはルールが要るかもですね。 - ノードに名前が付けられる。
付けられます。 - エッジには
type
を付けられる。
エッジにはいろいろ付けられます。
- グラフはスパース隣接行列で表現される。
スパース行列は、疎行列。隣接行列はグラフのエッジを行列で表すアレです。
使ってみたレベルの今は内部構造は気にしません。 - クエリ言語はCypherです。
Graph query language(GQL) standardへの取っ掛かりとなる直感的な言語らしいです。
まぁ確かに、
CREATE (:Idol {name:'如月千早'})-[:BelongTo]->(:Production {name:'765プロダクション'})
となり、上の図を形まで同じように記号で書き起こした感じ。
書くのは煩雑かもだけど、初学者でも読み取りやすいですね。
グラフを書いてみた
im@sparqlにアイドルとユニットの所属情報を問い合わせて、結果をredisgraphに書き込むやつです。Rustで書いてます。
これ何も難しいことしてないです...結果
{ "units": { "type": "literal" , "value": "ARCANA,ルナ,ハニーサウンド,Engage!,TORICO,ミッシングムーン,you-i,765ProAllstars,エターナルハーモニー,SLEEPING BEAUTY,765MillionStars,花鳥風月" } , "idol": { "type": "literal" , "value": "如月千早" } }
を分解して
"CREATE (:Idol {{name:'[アイドル名]'}})-[:memberOf]->(:Unit {{name: '[ユニット名]'}})"
上のやつにこんな感じで入れてるだけです。↓
for element in json { let units = element.units.value; let idol = element.idol.value; for unit in units.split(separator) { let create_query = format!( "CREATE (:Idol {{name:'{}'}})-[:memberOf]->(:Unit {{name: '{}'}})", idol, percent_decode(unit.as_bytes()) // ユニット名はエンコードされてるかも .decode_utf8() .unwrap() .to_string() .replace("'", "\\'") ); result = graph.mutate(&create_query); if !result.is_ok() { return result; } } println!("{}", idol); }
グラフに問い合わせてみた
redisgraphのQuickStart通り、redis-cli
コマンドを使って問い合わせます。
ここで注意なのが、--raw
オプションを付けなければ日本語が文字化けするということです。
というわけでクエリはこちら
GRAPH.QUERY imasparql "MATCH (i:Idol)-[:memberOf]->(u:Unit) WHERE i.name = '如月千早' RETURN i.name, u.name"
クエリは説明しなくてもなんとなく分かるよね?(逆に言えばなんとなく分かる程度にしか自分も説明できない...) 結果はこちら
i.name u.name 如月千早 ARCANA 如月千早 ルナ 如月千早 ハニーサウンド 如月千早 Engage! 如月千早 TORICO 如月千早 ミッシングムーン 如月千早 you-i 如月千早 765ProAllstars 如月千早 エターナルハーモニー 如月千早 SLEEPING BEAUTY 如月千早 765MillionStars 如月千早 花鳥風月 Query internal execution time: 1.649300 milliseconds
わぁ、羅列!
--raw
さえ付けなければ
127.0.0.1:6379> GRAPH.QUERY imasparql "MATCH (i:Idol)-[:memberOf]->(u:Unit) WHERE i.name = '黛冬優子' RETURN i.name, u.name" 1) 1) "i.name" 2) "u.name" 2) 1) 1) "\xe9\xbb\x9b\xe5\x86\xac\xe5\x84\xaa\xe5\xad\x90" 2) "Straylight" 3) 1) "Query internal execution time: 0.962100 milliseconds"
こんな感じで、塊ごとに分けてもらえるのですが....
まぁ、コマンドラインでやる人なんていないでしょうし、ソースコード上で使うクライアント次第じゃないでしょうか。
おわりに
使ってみた程度としてはこんな感じです。
今回はCREATE
とMATCH
をメインに使いましたが、他にも命令はあるみたいなのでもっと便利になるとは思います。
おまけ
GitHubのリポジトリを見て気付いたかもしれませんが、redisgraphにim@sparqlのアイドルとユニットの所属情報を書き込んでくれるDocker Imageを配布しています。
コンテナ生成時にim@sparqlへ問い合わせるので、生成しなおせば新鮮なグラフになります。
ユニット情報だけでなく、いろいろ追加していこうかと思っているので、im@sparqlでは速度に不満がある方はぜひ使ってみてください。