2011-09-24 14 views
18

私はグラフデータベースのモデリングに関する一般的な質問をしていますが、私の周りを包み込むことはできません。グラフデータベース(Neo4jなど)で実世界関係をモデル化する方法は?

このタイプの関係をどのようにモデル化しますか:「ニュートンは微積分を計算しました」? simple graph

、あなたはこのようにそれをモデル化することができます:あなたはより多くの人々や発明を追加したとして、あなたは「発明」のグラフ関係の束を持っていると思いますので...

Newton (node) -> invented (relationship) -> Calculus (node) 

問題はあなたが関係する性質の束を追加する必要が開始し、次のとおりです。

  • invention_date
  • influential_concepts
  • influential_people books_inventor_wrote

...とそれらのプロパティと他のノードとの間の関係を作成したいと思うでしょう:

  • influential_people:人・ノードとの関係
  • books_inventor_wrote:ノード

を予約する関係は、だから今、それは(「発明」)、「実世界の関係」のように思えるが、実際にあるノードでなければなりませんグラフ、およびグラフのようになります。

Newton (node) -> (relationship) -> Invention of Calculus (node) -> (relationship) -> Calculus (node) 

そして、もっと物事を複雑にするには、他の人もそう、微積分の発明に参加していますあなたには、いくつかのしたいことがあるので、あなたが実際のグラフデータベース「関係」オブジェクト、上のプロパティを設定したくないのように、それはそうなのでだから私は質問をする

Newton (node) -> 
    (relationship) -> 
    Newton's Calculus Invention (node) -> 
     (relationship) -> 
     Invention of Calculus (node) -> 
      (relationship) -> 
      Calculus (node) 
Leibniz (node) -> 
    (relationship) -> 
    Leibniz's Calculus Invention (node) -> 
     (relationship) -> 
     Invention of Calculus (node) -> 
      (relationship) -> 
      Calculus (node) 

:グラフは、今のようなものになりポイントをグラフのノードとして扱います。

これは間違いありませんか?

私はFreebase Metaweb Architectureを研究しており、すべてをノードとして扱っているようです。たとえば、FreebaseはMediator/CVTのアイデアを持っています。ここでは、「アクター」ノードを「フィルム」ノードにリンクする「パフォーマンス」ノードを作成できます(http://www.freebase.com/edit/topic/en/the_last_samuraiなど)。しかし、これが同じ問題であるかどうかは分かりません。

"現実の関係"が実際にグラフ関係ではなくグラフノードであるべきかどうかを判断するための指針は何ですか?

このトピックに関する良い本があれば、私は知りたいです。ありがとう!

答えて

18

invention_dateのようなものは、ほとんどのグラフデータベースと同じように、エッジとしてプロパティとして格納できます。エッジは、頂点にプロパティを持つのと同じ方法でプロパティを持つことができます。たとえば、あなたがこのような何か(コードがTinkerPop's Blueprintsを次の)行うことができます:

Vertex liebniz = graph.addVertex(null); 
liebniz.setProperty("given_name", "Gottfried"); 
liebniz.setProperty("surnam", "Liebniz"); 
liebniz.setProperty("birth_year", "1646"); 
liebniz.setProperty("type", "PERSON"); 

Edge liebniz_calculus = graph.addEdge(null, liebniz, calculus, "DISCOVERED"); 
liebniz_calculus.setProperty("year", 1674); 

をブックに追加:

Vertex principia = graph.addVertex(null); 
principia.setProperty("title", "Philosophiæ Naturalis Principia Mathematica"); 
principia.setProperty("year_first_published", 1687); 
Edge newton_principia = graph.addEdge(null, newton, principia, "AUTHOR"); 
Edge principia_calculus = graph.addEdge(null, principia, calculus, "SUBJECT"); 

Graph graph = new Neo4jGraph("/tmp/my_graph"); 
Vertex newton = graph.addVertex(null); 
newton.setProperty("given_name", "Isaac"); 
newton.setProperty("surname", "Newton"); 
newton.setProperty("birth_year", 1643); // use Gregorian dates... 
newton.setProperty("type", "PERSON"); 

Vertex calculus = graph.addVertex(null); 
calculus.setProperty("type", "KNOWLEDGE"); 

Edge newton_calculus = graph.addEdge(null, newton, calculus, "DISCOVERED"); 
newton_calculus.setProperty("year", 1666); 

を、少しそれを拡張し、Liebnizに追加することができます

ニュートンが発見したすべての本を調べるには、グラフトラバーサルを構築することができます。私たちはニュートンから始まり、彼が発見したものへのリンクをたどり、その逆のリンクをたどってその話題の本を手に入れ、再びリンクを逆にして著者を得る。作者がニュートンなら、本に戻り、結果を返します。

newton.out("DISCOVERED").in("SUBJECT").as("book").in("AUTHOR").filter{it == newton}.back("book").title.unique() 

私は巧妙なトラバーサルを表現するために中間ノードを作成して問題を回避するために使用することができますどのように私は少しを示してきました願って、このように:このクエリは、グラフトラバーサルのためのGroovyベースのドメイン固有言語は、Gremlinで書かれていますエッジ。小さなデータベースではそれほど重要ではありませんが、大きなデータベースでは、それを実行する大きなパフォーマンスヒットに苦しむでしょう。

はい、あなたがグラフ内の他のエッジとエッジを関連付けることができないという悲しいですが、それは、これらのデータベースのデータ構造の制限です。メディエータ/ CVTのようにすべてのノードをノードにするのが理にかなっていることもあります。パフォーマンスにはもう少し具体性があります。個人は、「最後のサムライ」でのトム・クルーズのパフォーマンスだけをアドバイスしたいかもしれません。しかし、ほとんどのグラフデータベースでは、いくつかのグラフトラバーサルを適用すると、データベースから必要なものを得ることができます。

+0

優れた回答!これは本当に私のために物事をクリアします、ありがとう。 –

関連する問題