2017-02-01 5 views
1

私が取り組んでいるアプリケーションのデータモデルを試してみようとしています。アプリケーションは現在Neo4jを使用しています。Neo4j:共有ノードを持つグラフをモデル化する方法にいくつかのプロパティに基づいて一意のパスを持つ方法の提案

基本モデルには、コース、テスト、質問の3種類があります。アプリケーションを使用すると、コースを作成してから、テスト(既存または新規)をコースに関連付けることができます。彼らはテストに質問を追加したり削除したりすることができますが、この追加と削除はグラフの他のコースやテストに影響しません。ここで

は、私は長所と短所と考えている別のモデルです:

1)にエッジを作成/削除質問するコースノード、テストノードへのエッジ、その後、テストでの作成コースidを持つエッジのプロパティを持つ質問。

match (c:COURSE {id:'123'})<--(t:TEST)-[r]->(q:QUESTION) where r.courseId='123' return c, t, q;

PROS:単純なデータモデルこのモデルではCYPHERクエリは次のようになります。最も明白な解決策。

CONS:2ノード間に数百のエッジがあると、パフォーマンスは実際にになります。コースから質問への単純なパスが1つもないため、すべてのエッジを評価/比較する必要があります。

2.)テストノードへのエッジであるコースノードを作成し、次にテストと質問の間のエッジについて、エッジのタイプとしてコースIDを使用します。このモデルではCYPHERクエリは次のようになります:

match (c:COURSE {id:'123'})<--(t:TEST)-[:123]->(q:QUESTION) return c, t, q;

PROSを:私の研究から、のNeo4jは、より良いモデリングのこのタイプを扱うようです。

CONS:エッジタイプの数に上限はありますか?数百または数千のコースがあれば、パフォーマンスが#1よりも良いかどうかはわかりません。

3.)コースノードとテストノードのエッジを作成し、コースIDのリストを使用してエッジを1つだけ作成します。

match (c:COURSE {id:'123'})<--(t:TEST)-[r]->(q:QUESTION) where r.courseIds contains '123' return c, t, q;(正しくない構文が、あなたのアイデアを得る)

PROS:まだかなり簡単なようだ

CONS:CYPHER場合はわからないでもこのモデルではCYPHERクエリは次のようになりますそのタイプのクエリをサポートします。 1つのエッジのプロパティリストをスキャンすると、1つのプロパティを持つすべてのエッジをスキャンするのと同じくらい悪いですか?

4.各コースのテストと質問のコピーを作成します。

PROS:パスが1つしかなく、比較が必要ないため、最も速いソリューションと思われます。コースから始め、グラフ全体をトラバースしてください。

結論:これは多くの冗長データをもたらすでしょう。このように、グラフを使用する目的を打ち破り、Cassandraやその他のデータストアでよりよくモデリングすることができます。

5)? - 私が見逃した他の提案をお探しください

基本的には、私は共有ノードを持つグラフを作成する最良の方法ですが、パフォーマンスが次の順序でないいくつかのプロパティに基づいて一意のパスを持っています可能な多数のプロパティ値に対して、トラバーサルが完了するまでの時間。

NOTES:

  • 私は#1を実装した、それは私が数百のコースが作成された後、クエリのパフォーマンスが悲惨であることを考え出した方法です。
  • 私はできるだけ明確な質問をするように努めましたが、もし私が何かを見逃してしまったら、明確化を求めてください。
  • 私は多くの見た目をしており、これをモデル化する良い方法を見つけていません。
+0

? – cybersam

答えて

1

コースIDを複数の場所に保存してから、後で一致するIDをクエリする必要はありません。

これは私にとって理にかなった簡単なモデルです。すべてのTestノードは、単一のCourseノードに関連し、複数の質問ノードに関連しています。

単一コースのための各テスト(との質問のコレクション)を検索するには、クエリは次のようになります。単一のテストは、単一のコースに関連付けないでください

MATCH (c:Course {id:'123'})<-[:FOR]-(t:Test)-[:HAS_QUESTION]->(q:Question) 
RETURN c, t, COLLECT(q) AS questions; 
+0

お返事ありがとうございます。それはずっと簡単ですが、問題を正確に解決するわけではありません。あなたの例では、Courseノードを作成するときに、新しいテスト(または複数のテスト)を作成する必要があります。私はこの質問を求めるためにモデルを単純化しようとしました。 – frantic1337

+0

テストのある種類のコースと、既に定義された質問のための「マスター」コースがあります。新しいコースが作成されると、既存のテストや質問に関連するマスター(コースノード)のコピーが作成されます。その後、ユーザーは必要に応じてこれらのテストと質問を変更できます。 ソリューションでは、各コースのテストのコピーを作成する必要があります。これは元々の質問から多かれ少なかれ#4に似ています。 – frantic1337

+0

注:ユーザーはノードの実際の値ではなく、関係を操作することしかできません。そのため、あらゆる種類のコピーでは重複データが発生します。可能であれば、エッジを変更するだけで、これを実現したいと思っています。 – frantic1337

関連する問題