グラフを格納するためのコンテナには、次の2つの一般的なタイプがあります。
真のグラフデータベース:例: Neo4J、agamemnon、GraphDB、AllegroGraph ; これらはグラフを格納するだけでなく、グラフがであると理解しているため、たとえば、これらのデータベースにクエリを実行できます。たとえば、ノードXとノードYからの最短パスの間にノードがいくつありますか。
静的グラフコンテナ:TwitterのMySQLに適合したFlockDBは、ここで最もよく知られている模範です。これらのDBは、グラフを適切に保存および取得できます。ただし、グラフ自体をクエリするには、最初にDBからグラフを取得してから、ライブラリ(Pythonの優れたNetworkxなど)を使用してグラフ自体をクエリする必要があります。
以下で説明するredisベースのグラフコンテナは2番目のカテゴリにありますが、redisでグラフデータベースを実装するための非常に小さなPythonパッケージであるredis-graphからもわかるように、redisは最初のカテゴリのコンテナにも適しているようです。
redisはここで美しく機能します。
Redisは、本番環境での使用に適した頑丈で耐久性のあるデータストアですが、コマンドライン分析にも使用できるほどシンプルです。
Redisは、複数のデータ構造タイプがあるという点で他のデータベースとは異なります。ここでお勧めするのはハッシュデータ型です。このredisデータ構造を使用すると、グラフを格納するための従来のスキーマである「ディクショナリのリスト」を非常に厳密に模倣できます。リスト内の各アイテムは、それらのエッジの元のノードにキー設定されたエッジのディクショナリです。
最初にredisとpythonクライアントをインストールする必要があります。DeGizmoブログには、両方をインストールするためのステップバイステップのガイドを含む、優れた「稼働中の」チュートリアルがあります。
redisとそのpythonクライアントがインストールされたら、redisサーバーを起動します。これは次のようにします。
これで、シェルウィンドウにサーバーログファイルの末尾が表示されます。
>>> import numpy as NP
>>> import networkx as NX
>>> # start a redis client & connect to the server:
>>> from redis import StrictRedis as redis
>>> r1 = redis(db=1, host="localhost", port=6379)
以下のスニペットでは、4ノードのグラフを保存しています。以下の各行は、redisクライアントでhmsetを呼び出し、1つのノードとそのノードに接続されているエッジを格納します( "0" =>エッジなし、 "1" =>エッジ)。(もちろん、実際には、これらの反復呼び出しを関数で抽象化します。ここでは、その方法を理解しやすいため、各呼び出しを示しています。)
>>> r1.hmset("n1", {"n1": 0, "n2": 1, "n3": 1, "n4": 1})
True
>>> r1.hmset("n2", {"n1": 1, "n2": 0, "n3": 0, "n4": 1})
True
>>> r1.hmset("n3", {"n1": 1, "n2": 0, "n3": 0, "n4": 1})
True
>>> r1.hmset("n4", {"n1": 0, "n2": 1, "n3": 1, "n4": 1})
True
>>> # retrieve the edges for a given node:
>>> r1.hgetall("n2")
{'n1': '1', 'n2': '0', 'n3': '0', 'n4': '1'}
グラフが永続化されたので、RedisDBからNetworkXグラフとして取得します。
これを行うには多くの方法がありますが、以下の2つの*ステップ*で行いました。
データをredisデータベースから隣接行列に抽出し、2DNumPy配列として実装します。それから
NetworkX
組み込み関数を使用して、これをNetworkXグラフに直接変換します。
コードに還元すると、これらの2つのステップは次のとおりです。
>>> AM = NP.array([map(int, r1.hgetall(node).values()) for node in r1.keys("*")])
>>> # now convert this adjacency matrix back to a networkx graph:
>>> G = NX.from_numpy_matrix(am)
>>> # verify that G in fact holds the original graph:
>>> type(G)
<class 'networkx.classes.graph.Graph'>
>>> G.nodes()
[0, 1, 2, 3]
>>> G.edges()
[(0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (3, 3)]
redisセッションを終了すると、次のようにクライアントからサーバーをシャットダウンできます。
>>> r1.shutdown()
redisはシャットダウンする直前にディスクに保存するので、これはすべての書き込みが永続化されていることを確認するための良い方法です。
では、redis DBはどこにありますか?これは、デフォルトのファイル名(ホームディレクトリのdump.rdb )でデフォルトの場所に保存されます。
これを変更するには、redis.confファイル(redisソースディストリビューションに含まれています)を編集します。次で始まる行に移動します。
# The filename where to dump the DB
dbfilename dump.rdb
dump.rdbを任意の名前に変更しますが、.rdb拡張子はそのままにしておきます。
次に、ファイルパスを変更するには、redis.confで次の行を見つけます。
# Note that you must specify a directory here, not a file name
その下の行は、redisデータベースのディレクトリの場所です。あなたが望む場所を引用するようにそれを編集してください。リビジョンを保存し、このファイルの名前を変更しますが、拡張子は.confのままにします。この構成ファイルは任意の場所に保存できます。redisサーバーを起動するときに、このカスタム構成ファイルのフルパスと名前を同じ行に入力するだけです。
したがって、次にRedisサーバーを起動するときは、次のようにする必要があります(シェルプロンプトから:
$> cd /usr/local/bin # or the directory in which you installed redis
$> redis-server /path/to/redis.conf
最後に、Python Package Indexは、redisでグラフデータベースを実装するためのパッケージをリストしています。パッケージはredis-graphと呼ばれ、私はそれを使用していません。