2017-11-27 3 views
0

Wie kann ich den Prozentsatz eines Attributs für alle Verbindungen eines sozialen Netzwerks berechnen? In diesem speziellen Beispiel würde ich möchte die Betrügerei eines Benutzers berechnen, indem seine Wechselwirkungen Bewertung (Anruf, SMS):neo4j Prozentsatz des Attributs für soziales Netzwerk

CREATE (Alice:Person {id:'a', fraud:1}) 
CREATE (Bob:Person {id:'b', fraud:0}) 
CREATE (Charlie:Person {id:'c', fraud:0}) 
CREATE (David:Person {id:'d', fraud:0}) 
CREATE (Esther:Person {id:'e', fraud:0}) 
CREATE (Fanny:Person {id:'f', fraud:0}) 
CREATE (Gabby:Person {id:'g', fraud:0}) 
CREATE (Fraudster:Person {id:'h', fraud:1}) 


CREATE 
    (Alice)-[:CALL]->(Bob), 
    (Bob)-[:SMS]->(Charlie), 
    (Charlie)-[:SMS]->(Bob), 
    (Fanny)-[:SMS]->(Charlie), 
    (Esther)-[:SMS]->(Fanny), 
    (Esther)-[:CALL]->(David), 
    (David)-[:CALL]->(Alice), 
    (David)-[:SMS]->(Esther), 
    (Alice)-[:CALL]->(Esther), 
    (Alice)-[:CALL]->(Fanny), 
    (Fanny)-[:CALL]->(Fraudster) 

Beim Versuch, die Abfrage wie:

MATCH (a)-->(b) 
WHERE b.fraud = 1 
RETURN (count()/(MATCH (a) -->(b) RETURN count()) * 100) 

ich den folgenden Fehler anzeigen :

Invalid input '>': expected 0..9, '.', UnsignedHexInteger, UnsignedOctalInteger or UnsignedDecimalInteger (line 3, column 33 (offset: 66)) 
"RETURN (count()/(MATCH (a) -->(b) RETURN count()) * 100)" 
           ^

enter image description here

Antwort

1

Diese Abfrage wird der Anteil der Verbindungen zu jedem Betrug zurück:

MATCH (:Person)-[:CALL|:SMS]->(f:Person) 
WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs 
UNWIND fs AS f 
WITH divisor, f 
WHERE f.fraud = 1 
RETURN f, COUNT(*)/divisor AS percentage 

Mit den Beispieldaten, ist das Ergebnis:

+----------------------------------------------+ 
| f      | percentage  | 
+----------------------------------------------+ 
| Node[13]{id:"h",fraud:1} | 9.090909090909092 | 
| Node[6]{id:"a",fraud:1} | 9.090909090909092 | 
+----------------------------------------------+ 

Diese Abfrage benötigt nur einen einzigen Scan des DB und ist explizit über den Knoten Etiketten und Beziehungstypen - alle anderen Daten herauszufiltern, die in th sein könnte e DB.

+0

Großartig. Ist es auch möglich, die Knoten in der Zeichnung von Neo4j entsprechend dem Prozentsatz zu färben? Es scheint nur in der Tabellenansicht verfügbar zu sein - nicht in der grafischen Darstellung. Außerdem: ist '[: CALL |: SMS * 1..3]' der richtige Weg, um mehrere Ebenen anzusprechen?Sie erwähnen Leistung: Wäre es möglich, 3 Arten von Aggregationen (alle - wie Sie es taten, nur SMS, nur Telefon) in einem einzigen Durchlauf über die Grafik? –

+0

Mit der Browser-Benutzeroberfläche von neo4j können Sie die Knotenfarbe nur nach Label und nicht nach dem Eigenschaftswert festlegen. Und, ja, Sie können '[: CALL |: SMS * .. 3]' für Pfade mit 1 bis 3 übereinstimmenden Beziehungen verwenden. – cybersam

+0

Wie für die 2 zusätzlichen Arten der Aggregation ist es nicht klar, was Sie wollen. Sind Sie nur an Pfaden (von bis zu 3 Beziehungen) interessiert, in denen jede Beziehung den gleichen Typ hat? – cybersam

1

In Ihrem RETURN Abschnitt rufen Sie eine neue Abfrage auf: MATCH (a) -->(b) RETURN count().

Dies ist nicht in Neo4j erlaubt, können Sie eine Unterabfrage mit dem WITH Schlüsselwort für das machen sollten:

MATCH()-->() 
WITH count(*) AS total 
    MATCH()-->(b) 
    WHERE b.fraud = 1 
    RETURN toFloat(count(*))/total * 100 

Oder in Ihrem Fall, weil Sie nur die Gesamtzahl der Beziehung wollen in Ihrer DB, Sie können diese Abfrage machen:

MATCH()-->(b) 
WHERE b.fraud = 1 
RETURN toFloat(count(*))/size(()-->()) * 100 

Updates

  • Hinzufügen toFloat auf Chiffre-Abfragen, da sonst die Division eine ganze geben keinen Schwimmer
+0

'count()' wirft: 'Unzureichende Parameter für Funktion 'count'' –

+0

Sorry, ich habe das' * '... vergessen – logisima

+0

Kein Problem, aber dies berücksichtigt nur die direkten Nachbarn. Wenn ich stattdessen (iterativ) in das Netzwerk jedes Anwenders vordringen möchte - nehmen wir an, bis zu einer Tiefe von 3. Wie könnte dies integriert werden? Auch die zurückgegebenen Ergebnisse sind 0, was mir seltsam vorkommt. –

Verwandte Themen