中国語学習×グラフデータベース(13) - 細々気づいたこと
一通りデータは登録してみたので、細々したことをいくつか。
重複ノードの削除
データを登録する際に、いろいろ間違えてしまい不要なノードを削除したいなという時があった。通常のリレーショナルDB(以下RDB)では、テーブル定義の時にキーの重複を許さないように設定しておけば良いが、Neo4jを触った限りでは、単一項目での重複を許さないという設定は出来るものの、例えば単語(Word)のように、keywordとpinyinの組み合わせでの重複を許さないというような設定は出来ない(ように見える)。
今回の取り組みの中でも、自分の作ったコードの考慮が足りなかったために、同じ単語のノードが重複したときの削除に少しハマった。
で、どうしたらいいかをいろいろググると、StackoverflowではSKIPを使う方法が紹介されていたが、直感的にイマイチだと思ったので、ここに注目してみた。
わかりにくいと思うが、どのNodeにも
match (w1:Word {autoadd:True}), (w2:Word {autoadd:True}) where w1.keyword=w2.keyword and id(w1)<id(w2) return w2.keyword, id(w1), id(w2)
これは算数の問題だが、普通にやると単語の組み合わせが無数にある(5800の2乗で3000万通り以上)ため、処理に恐ろしく時間がかかるのだが、自分の場合、この手の重複はautoadd=Trueで登録した単語に限られることが分かっていたので、そこで絞り込むことができた。
2つの単語のidを比較して、単語(keyword)は同じだがidが異なる(どちらか一方を消せば良いので、<でさらに絞っている)を出力してくれと実行すると、消すべきidが4つほどに絞り込まれたので、今度はこんなcypherクエリを実行した。
match (w:Word)-[r:is_similar_to]-(w2:Word) where id(w) in [6458, 6461, 6469, 6497] delete w, r
Neo4jでは、Nodeの消去を行うには、Relationshipに紐付いていない事という条件があるため、Relationshipも同時に削除しなくてはならないので、こんな書き方をしている。実行結果は、こんな感じ。
Deleted 4 nodes, deleted 14 relationships, statement executed in 98 ms.
Node 4つに加えて、Relationshipが14個も削除されたことが分かる。上の2つは、Webインターフェイスから直接Cypherクエリを実行したが、もちろんgraph.cypher.execute()でpython側から実行しても結果は同じだ。
すべてが嫌になったときは
前も書いたが、これですべて消せる。
graph.delete_all()
消すなんてもったいないと思うかもしれないが、Jupyter Notebookでログを残しながらやっていれば、同じコードを再実行するのは簡単なので、結構あっさりと復元できるはずだ。
一通り、今回触ってきた内容については、ブログ上で整理したつもり。また何か進捗があれば、ここに書いていく予定。
(つづくかも)
- 作者: Neo4jユーザーグループ,長瀬嘉秀
- 出版社/メーカー: リックテレコム
- 発売日: 2016/02/13
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
グラフデータベース ―Neo4jによるグラフデータモデルとグラフデータベース入門
- 作者: Ian Robinson,Jim Webber,Emil Eifrem,佐藤直生,木下哲也
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/03/25
- メディア: 大型本
- この商品を含むブログ (2件) を見る
A Programmatic Introduction to Neo4j
- 作者: Jim Webber,Ian Robinson
- 出版社/メーカー: Addison-Wesley Professional
- メディア: ペーパーバック
- この商品を含むブログを見る