2013-10-21 4 views
7

次のように私のCYPHERクエリがある(私は部門で購入しているユーザーを見つけるために探しています)階層的なスタイルのクエリはCypherで驚異的なパフォーマンスを示します。Traverser APIを使用する必要がありますか?

START n=node:sectors('SECTOR_ID:65, SECTOR_ID:66 ...') // 20 sectors 
MATCH (n)-[:HAS_DOMAIN]->(dom)-[:HAS_CAT]->(cat)<-[:BELONGS_TO]-(prod)-[:BOUGHT_BY]->(user) 
RETURN n.sector_name, COUNT(user), COLLECT(DISTINCT(product.name)), ... etc. 

私はすべてのトラバーサルにパスの数が指数関数的に上昇するので、 最終クエリが結果を持っていることを見つけます25秒の時間。 つまり、セクターに50のドメインがある場合、各ドメインは1000のカテゴリを持ち、各カテゴリ は250K ++の製品を持っています。

これは私には「スーパーノードの問題」と思われます...またはあまりにも多くのパスがあります!

Traverser APIを使用すべきですか? データを別の方法でモデル化する必要がありますか?

のNeo4j 1.8.3、Linuxの

ありがとう!

+0

「WITH」で2つのクエリを分割すると、違いはありますか?私は決してこのようなオープンエンドのパターンを疑問視しているとは思わないが、私の感覚はメモリ使用量をプロファイルし、同じクエリが壊れたものと比較することである。私はそれが残りの部分を続ける前にパターンの前半を完全にマッチングさせることを期待するので、「..」。ファジィ・ハンチング警告欄。 – jjaderberg

+0

ここでは数多くのことが起こっている可能性があります。まず、セクターのルックアップを実行します。それぞれに1秒かかります。 ユーザーから検索を再試行しましたか?購入したすべてのユーザーが、存在する関係に基づいてセクターに戻ることができますか? –

+0

@Mikeいいえ、ルック・アップにはわずか数ミリ(Luceneを通して)しかかかりません。 パスが掛け算されるとコストが大きくなり始めます。 いいえ、私はユーザーから始めることはできません。セクターごとのユーザーに関する集計統計を取得したいと思います。 @jjaderberg。 – Nikos

答えて

0

すべてのパスをロードしようとすると、主な問題は実際にはメモリです。必要な統計情報があれば、Traverser APIを使って、ノードのロード/集計の方法を制御できるようになります。

Cypherに固執したいのであれば、各セクターを独自のクエリに分割して、並列でよりうまく実行できるようにすることができます。データベースの読み取り/書き込みを完全に制御している場合は、読み取り/書き込み時に更新できるレジャーノードを作成する別のオプションもあります。そうすれば、すべてのパスを知る必要はなく、この1つの変更がどのように統計に影響を与えるかだけです。また、各試合で、あなたが戻って列の元の数に統合することができ、そのように面白いのノードへのセクターからの直接の関係を作成し、ちょうど

(sector)-[:HAS_CAT]->(cat) 
WITH sector, collect(cat.name) as Categories 

のような単一の要素に必要な情報を収集することができます。

関連する問題