2

次の構造を持ついくつかのクライアント データに似たテスト データセットを作成しました。

   *1                100k              *3..30
[:author]-------->  person  <---------[:member]
    |                 |                  |
    |               *2..8                |
    |              [:topic]              |
    |                 |                  |
    |    *3..8        V        *3..8     |
article-[:topic]->  topic  <-[:topic]- project
    1m                1k                 20k

数字は、たとえば、100 万の記事があり、それぞれに 1 人の著者がいて、各記事には 1000 のトピックのうちの 1 つに対する 3 ~ 8 の関連があります。

今、私は2つの質問があります:

最初: このレイアウトは理にかなっていますか? トピックはスーパーノードになります。ノードの属性として持つ方がよいでしょうか?

2 つ目は、クエリの表現方法によって、クエリのパフォーマンスに大きな違いがあることです。アイデアは、プロジェクトに一緒に取り組んでいて、トピックに個人的な関心を共有している人々を見つけることです:

クエリ1

match 
    n:person<-[:member]-p:project-[:member]->m, 
    n-[:topic]->t,
    m-[:topic]->t 
where 
    n.name='person1215' and 
    n<>m 
return 
    m,t;

これは範囲内に戻り1500ms-9000msます。

query2ははるかに高速です。

match 
    n:person<-[:member]-p:project-[:member]->m, 
    n-[:topic]->t1, 
    m-[:topic]->t2  
where 
    n.name='person1250' and 
    n<>m and 
    t1=t2 
return 
    t1,m;

に戻ります200ms-400ms

2 番目: なぜ query2 の方がはるかに高速なのですか? そのクエリを見るだけで、それをどのように確認できますか?

query1のプロファイラー出力:

ColumnFilter(symKeys=["n", "t", "m", "  UNNAMED14", "p", "  UNNAMED51", "  UNNAMED35", "  UNNAMED66"], returnItemNames=["m", "t"], _rows=3, _db_hits=0)
Filter(pred="((NOT(n == m) AND hasLabel(p: project)) AND hasLabel(p: project))", _rows=3, _db_hits=0)
  PatternMatch(g="(p)-['  UNNAMED35']-(m),(p)-['  UNNAMED14']-(n),(m)-['  UNNAMED66']-(t),(n)-['  UNNAMED51']-(t)", _rows=3, _db_hits=0)
    SchemaIndex(identifier="n", _db_hits=0, _rows=1, label="person", query="Literal(person1215)", property="name")

およびquery2の場合:

ColumnFilter(symKeys=["n", "  UNNAMED67", "m", "  UNNAMED14", "t2", "p", "  UNNAMED51", "t1", "  UNNAMED35"], returnItemNames=["t1", "m"], _rows=2, _db_hits=0)
Filter(pred="(((NOT(n == m) AND t1 == t2) AND hasLabel(p: project)) AND hasLabel(p: project))", _rows=2, _db_hits=0)
  PatternMatch(g="(p)-['  UNNAMED35']-(m),(p)-['  UNNAMED14']-(n),(m)-['  UNNAMED67']-(t2),(n)-['  UNNAMED51']-(t1)", _rows=2, _db_hits=0)
    SchemaIndex(identifier="n", _db_hits=0, _rows=1, label="person", query="Literal(person1250)", property="name")

どうもありがとう、

ヨルグ

4

1 に答える 1

1

Joerg さん、パターン マッチャーの選択でバグを見つけたのかもしれません。これらのクエリは実際にはトラバーサル マッチャーを使用する必要があります。

GitHub の問題が発生した場合は、フォローアップします。どうもありがとう!!

「スーパーノード」トピックの場合、ノードの関係のサブ組織 (メモリ内) を可能にする、あまり一般的ではない関係タイプを使用することが理にかなっている場合があります。例: :project_topic, article_topic, :interest_topic. これを試していただけますか?

次に、クエリは次のようになります。

match 
    n:person<-[:member]-p:project-[:member]->m, 
    n-[:interest_topic]->t,
    m-[:interest_topic]->t 
where 
    n.name='person1215' and 
    n<>m 
return 
    m,t;

ところで。ノード固有の制約により、m実際には n と同じであってはなりません。クエリでそれを見ましたか?

2 番目のラベル チェックを終了するとどうなるかも興味深いでしょう ( については:project、ちょっと興味があります)。

また、2.0 はまだパフォーマンスが最適化されていないことに注意してください。専用の人物検索の場合、GA に近づくとはるかに高速になります。

于 2013-08-09T01:49:17.120 に答える