2016-12-02 10 views
1

Neo4jを使用して、潜在的に不正なカード取引をほぼリアルタイムで検出する方法を検討しています。私はオンラインシステムから、彼らが使ったカードと顧客の詳細を受け取ります。私がここでやろうとしているのは、顧客とカードのための新しいノードを作成し、それが存在しない場合はそれらの関係を確立することです。Neo4j:ノード数の維持

お客様がカードを使用するたびに、カードが最後に使用された時間を設定する必要があります。さらに、この顧客とカードの関係が初めて確認された場合は、顧客が関連していること、およびカードに関連付けられている顧客の数。

以下のCypherはうまくいくようですが、作成時だけでなく、関係が確認されるたびにカウントが再評価されると思います。このステートメントでON MATCHとON CREATEを使用して不要な処理を制限することはできますか?

MERGE (c:customers {customer_id:"12345678"}) 
MERGE (a:cards {card_hash:"45uIic..."}) 
MERGE (c)-[r:has_card]->(a) 
set r.last_transaction = "30-NOV-2016 07:58:42" 
set a.card_ct = size(()-[:has_card]->(a)) 
set c.card_count = size((c)-[:has_card]->()) 

私は(py2neoを使用して)のPythonからこれを実行しています、私はまた、私は近所の別注ダイクストラ基づいて検索をキックオフすることができます戻って何かを返したいです。これが新しい関係か既存の関係かに基づいて、どのように変数を返すかというアイデアはありますか?

答えて

0

このような場合はどうですか。 MATCH上にカウンタを作成し、カウンタが0より大きい場合は、既存の関係になります。それ以外の場合は、新しい関係です。

MERGE (c:customers {customer_id:"12345678"}) 
MERGE (a:cards {card_hash:"45uIic..."}) 
MERGE (c)-[r:has_card]->(a) 
ON MATCH SET r.num = coalesce(r.num, 0) + 1 
set r.last_transaction = "30-NOV-2016 07:58:42" 
set a.card_ct = size(()-[:has_card]->(a)) 
set c.card_count = size((c)-[:has_card]->()) 
RETURN 
CASE 
    WHEN r.num > 0 THEN false 
    ELSE true 
END as new_relationship 
+1

ありがとう、それは私が必要なものです。また、各行に新しいSETを使用すべきではないことに気付きました。ON MATCHに続く文を区切るためにカンマを使用するだけで、必要な処理が実行されます。 – Alun

3

あなたもcard_ctまたはcard_count性質を持っている必要はありません。

neo4j 2.1以降、特定のタイプの関係の数をノードから得ることは非常に効率的です。したがって、カウントが必要なたびに、SIZE(()-[:has_card]->(node))またはSIZE((node)-[:has_card]->())を使用してください。

+0

私はNeo4jブラウザに表示されるように、ノード上のリレーションシッププロパティの数を保持していますが、カード(または銀行、電話番号など)に関連付けられている顧客の数を確認すると便利です。カード番号のハッシュなどの詳細。顧客にとっては、ノードを拡張しようとする前に、それらが関連付けられているカードの数などをカウントすると便利です。 – Alun

+2

ブラウザで視覚化しやすいものに基づいてデータモデルを設計するべきではありません。実際のユースケースが効率的になるように設計する必要があります。あなたはいつも私が提案した方法でブラウザでクエリを実行し、結果を数えて注文し、ブラウザで結果を表形式またはテキスト形式で見ることができます。 – cybersam

0

私は、彼の提案のためにDave Bennettに感謝しました。また、1人の顧客だけが1つのカードに関連付けられている場合、これ以上の分析を開始する必要はないので、これも除外しました。

MERGE (c:customers {customer_id:"12345678"}) 
MERGE (a:cards {card_hash:"BFgn..."}) 
MERGE (c)-[r:has_card]->(a) 
ON CREATE SET a.card_scheme = "VISA DEBIT" 
      , a.card_ct = size(()-[:has_card]->(a)) 
      , c.card_count = size((c)-[:has_card]->()) 
ON MATCH SET r.ind = 1 
SET r.last_transaction = "06-Dec-2016 11:19:13" 
RETURN CASE WHEN exists(r.ind) 
       AND a.card_ct + c.card_count > 2 
       THEN false 
       ELSE true END as new_relationship 
関連する問題