2017-04-10 3 views
0

Ich habe diese Abfrage DISTINCT Eigenschaft haben, die alle von der Beiträge des Benutzers zurückgibt, die kommentiert wurden: Dies funktioniert, dass neben großenWie DISTINCT Knoten sammeln, die

MATCH (author:User {user_id: { user_id }}) 

    MATCH (post:Post)<-[:AUTHOR]-(author) 
    WHERE post.createdAt < { before } 

    MATCH (post)-[:HAS_COMMENT]->(comment:Comment)<-[:AUTHOR]-(commentAuthor:User) 
    WHERE NOT author.user_id = commentAuthor.user_id 

    WITH 
    author, 
    post, 
    comment, 
    commentAuthor, 
    count(DISTINCT commentAuthor) as participantsCount, 
    count(comment) as commentsCount 
    ORDER BY comment.createdAt DESC 

    RETURN collect(DISTINCT post { 
    .*, 
    author, 
    commentAuthor, 
    commentCreatedAt: comment.createdAt, 
    participantsCount, 
    commentsCount 
    })[0..{ LIMIT }] as posts 

, wenn der gleiche Benutzer entscheidet und Kommentare Troll Im selben Post mehrmals wird dieser Post für denselben Benutzer mehrfach zurückgegeben. Dies macht für einige Spam-Benachrichtigungen:

user1 commented on your post "what's your favorite book?" 
user2 commented on your post "what's your favorite movie?" 
user3 commented your post "what's your favorite show?" 
user3 commented your post "what's your favorite show?" 
user3 commented your post "what's your favorite show?" 

^alle user3 Kommentare für diesen Beitrag

Wenn möglich zurück zu bekommen, würde Ich mag nur die unterschiedlichen Beiträge mit deutlichen Kommentar Autor, nach jüngsten bestellt sammeln.

user1 commented on your post "what's your favorite book?" 
user2 commented on your post "what's your favorite movie?" 
user3 commented your post "what's your favorite show?" 

^nur Renditen user3 jüngster Kommentar

Ich bin im Grunde genommen entlang der Linien von etwas zu tun versucht:

collect (DISTINCT post { DISTINCT commentAuthor ... ]) 
+1

Soweit ich sagen kann, Ihre Abfrage würde immer 1 für TeilnehmerCount und commentsCount für jede Zeile zurückgeben. Siehst du das auch, oder bekommst du die erwarteten Ergebnisse? – InverseFalcon

+0

Guter Fang ... Ich zeige das nicht sofort in der Benutzeroberfläche an, also habe ich es verpasst, aber ja, es wird fälschlicherweise 1 - 1 für diese Anzahl zurückgegeben. – kayla

+0

Arbeiten an einer alternativen Abfrage. Ist 'comment.createdAt' ein numerischer Zeitstempel? – InverseFalcon

Antwort

1

Ihre commentCreatedAt Karte Eigenschaft ist wahrscheinlich der Täter hier, wie Sie habe unterschiedliche Zeitstempel pro Kommentar. Sie müssen wahrscheinlich den neuesten Kommentar abrufen. Wenn Sie also max(comment.createdAt) verwenden (wenn es sich um einen numerischen Zeitstempel handelt), sollten diese Zeilen zusammenbrechen.

Lassen Sie uns auch Ihre Zählungen korrigieren. Beachten Sie, dass Ihre Aggregationen nur eine Bedeutung in Bezug auf die Nicht-Aggregationsspalten haben, die als Gruppierungsschlüssel fungieren. Da Sie jeweils comment und commentAuthor in einer Reihe in Ihrem MIT haben, ergeben Ihre Aggregationen 1 für participantsCount und commentsCount (da sie aggregieren in Bezug auf jeden einzelnen Kommentar in jeder Zeile, nicht alle Kommentare).

Sie benötigen eine Möglichkeit, um die Aggregation für Ihre Kommentare entweder eigenständig zu erhalten (indem Sie comment aus der Zeile entfernen) oder indem Sie die Kommentare sammeln oder aggregieren.

Hier ist ein Ansatz, bei dem wir zuerst die Kommentarinformationen sammeln, die wir pro KommentarAuthor benötigen, und dann sammeln wir die KommentareAutorinfo per Post, die uns auch die Gesamtanzahl der Kommentare und Teilnehmer per Post aggregieren lassen.

Um die Ausgabe der Abfrage in Ihrer Beschreibung zu vergleichen, werden wir die Autoren auflösen und die Beiträge zusammen mit jedem commentAuthor in einem eigenen Eintrag sammeln.

MATCH (post)-[:HAS_COMMENT]->(comment:Comment)<-[:AUTHOR]-(commentAuthor:User) 

    WITH 
    post, 
    commentAuthor, 
    // since we don't have a comment per line, we can aggregate across all comments per post/commentAuthor 
    max(comment.createdAt) as lastReplyAt, 
    count(comment) as commentsPerCommenter 
    ORDER BY lastReplyAt DESC 

    WITH post, 
    // able to sum across all comments/commenters per post since we're collecting commentAuthor 
    sum(commentsPerCommenter) as commentCount, 
    collect(commentAuthor {.*, lastReplyAt, 
     commentCount:commentsPerCommenter}) as commentAuthors 

    WITH post, 
    commentCount, 
    size(commentAuthors) as participantsCount, 
    commentAuthors 

UNWIND commentAuthors as author 

RETURN collect(post { 
    .*, 
    author, 
    commentCount, 
    participantsCount 
    })[0..5] as posts 

Wenn Sie jedoch pro Zeile ein Post wollen, in jedem Beitrag die commentAuthor Informationen aggregiert, diese Abfrage könnte besser für Sie arbeiten:

MATCH (post)-[:HAS_COMMENT]->(comment:Comment)<-[:AUTHOR]-(commentAuthor:User) 

    WITH 
    post, 
    commentAuthor, 
    max(comment.createdAt) as lastReplyAt, 
    count(comment) as commentsPerCommenter 
    ORDER BY lastReplyAt DESC 

    WITH post, 
    sum(commentsPerCommenter) as commentCount, 
    collect(commentAuthor {.*, lastReplyAt, 
     commentCount:commentsPerCommenter}) as commentAuthors 

RETURN post {.*, 
    commentCount, 
    participantsCount:size(commentAuthors), 
    commentAuthors} 
LIMIT 5 

Obwohl diese letzte Abfrage 5 Beiträge in jedem Fall zurückgibt , da jeder Beitrag eine eigene Zeile hat, anstatt dass er pro KommentarAuthor dupliziert wird.