Refactored the Cypher query for notifications

This commit is contained in:
Wolfgang Huß 2020-03-11 11:03:03 +01:00
parent 5dfd0f9ada
commit ee60bf7e15
5 changed files with 172 additions and 102 deletions

View File

@ -45,25 +45,94 @@ export default {
const readTxResultPromise = session.readTransaction(async transaction => {
const notificationsTransactionResponse = await transaction.run(
`
// Wolle MATCH (resource)-[notification:NOTIFIED]->(user:User {id:$id})
// WHERE
// ((labels(resource)[0] in ["Post", "Comment"] AND NOT resource.deleted AND NOT resource.disabled)
// OR labels(resource)[0] in ["Report"])
// ${whereClause}
// WITH user, notification, resource,
// [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors,
// [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author)} ] AS posts,
// [(reportedResource)<-[:BELONGS_TO]-(resource)<-[file:FILED]-(user) | file {.*, reportedResource: apoc.map.merge(properties(reportedResource), {__typename: labels(reportedResource)[0]})} ] AS files
// WITH resource, user, notification, authors, posts, files,
// resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0], filed: files, resource: files[0].reportedResource} AS finalResource
// RETURN notification {.*, from: finalResource, to: properties(user)}
// ${orderByClause}
// ${offset} ${limit}
MATCH (resource)-[notification:NOTIFIED]->(user:User {id:$id})
WHERE
((labels(resource)[0] in ["Post", "Comment"] AND NOT resource.deleted AND NOT resource.disabled)
OR labels(resource)[0] in ["Report"])
${whereClause}
WITH user, notification, resource,
[(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors,
[(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author)} ] AS posts,
[(reportedResource)<-[:BELONGS_TO]-(resource)<-[file:FILED]-(user) | file {.*, reportedResource: apoc.map.merge(properties(reportedResource), {__typename: labels(reportedResource)[0]})} ] AS files
WITH resource, user, notification, authors, posts, files,
resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0], filed: files, resource: files[0].reportedResource} AS finalResource
RETURN notification {.*, from: finalResource, to: properties(user)}
CALL apoc.case(
[
labels(resource)[0] = "Post", '
MATCH (resource)<-[:WROTE]-(author:User)
RETURN resource {.*, __typename: labels(resource)[0], author: author} AS finalResource',
labels(resource)[0] = "Comment", '
MATCH (author:User)-[:WROTE]->(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(postAuthor:User)
RETURN resource {.*, __typename: labels(resource)[0], author: author, post: apoc.map.merge(properties(post), {__typename: labels(post)[0], author: properties(postAuthor)})} AS finalResource',
labels(resource)[0] = "Report", '
MATCH (reportedResource)<-[:BELONGS_TO]-(resource)<-[filed:FILED]-(user)
RETURN {__typename: "FiledReport", reportId: resource.id, createdAt: filed.createdAt, reasonCategory: filed.reasonCategory, reasonDescription: filed.reasonDescription, resource: apoc.map.merge(properties(reportedResource), {__typename: labels(reportedResource)[0]})} AS finalResource'
],
'',
{
resource: resource,
user: user
}) YIELD value
RETURN notification {.*, from: value.finalResource, to: properties(user)}
${orderByClause}
${offset} ${limit}
// Wolle
// the UNION ALL with ORDER BY and SKIP, LIMIT is possible since Neo4j 4.0. See https://neo4j.com/docs/cypher-manual/4.0/clauses/call-subquery/#subquery-post-union
// refactor the following to the new CALL {} subquery
// MATCH (author:User)-[:WROTE]->(post:Post)-[notification:NOTIFIED]->(user:User {id: $id})
// WHERE NOT post.deleted AND NOT post.disabled
// ${whereClause}
// WITH user, notification, post {.*, __typename: labels(post)[0], author: properties(author)}
// RETURN notification {.*, from: post, to: properties(user)}
// UNION ALL
// MATCH (author:User)-[:WROTE]->(comment:Comment)-[:COMMENTS]->(post:Post)<-[:WROTE]-(postAuthor:User),
// (comment)-[notification:NOTIFIED]->(user:User {id: $id})
// WHERE NOT comment.deleted AND NOT comment.disabled
// ${whereClause}
// WITH user, notification, comment {.*, __typename: labels(comment)[0], author: properties(author), post: apoc.map.merge(properties(post), {__typename: labels(post)[0], author: properties(postAuthor)})}
// RETURN notification {.*, from: comment, to: properties(user)}
// UNION ALL
// MATCH (reportedResource)<-[:BELONGS_TO]-(report)<-[file:FILED]-(user:User {id:$id}),
// (report:Report)-[notification:NOTIFIED]->(user)
// WHERE (reportedResource:User) OR (reportedResource:Post) OR (reportedResource:Comment)
// ${whereClause}
// // Wolle - Here the three different case are not distinguished and therefore Post is not added to Comment and the authors are not added etc.
// WITH
// user,
// notification,
// {
// __typename: "FiledReport",
// createdAt: file.createdAt,
// reasonCategory: file.reasonCategory,
// reasonDescription: file.reasonDescription,
// reportId: report.id,
// resource: apoc.map.merge(properties(reportedResource), {
// __typename: labels(reportedResource)[0]
// })
// } AS filedReport
// RETURN notification {.*, from: filedReport, to: properties(user)}
// ${orderByClause}
// ${offset} ${limit}
`,
{ id: currentUser.id },
)
log(notificationsTransactionResponse)
return notificationsTransactionResponse.records.map(record => record.get('notification'))
// Wolle return notificationsTransactionResponse.records.map(record => record.get('notification'))
const notification = notificationsTransactionResponse.records.map(record => record.get('notification'))
// Wolle console.log('notification: ', notification)
return notification
})
try {
const notifications = await readTxResultPromise

View File

@ -230,26 +230,47 @@ describe('given some notifications', () => {
... on Comment {
content
}
... on Report {
id
filed {
reasonCategory
reasonDescription
reportedResource {
__typename
... on User {
id
name
}
... on Post {
id
title
content
}
... on Comment {
id
content
}
# Wolle ... on Report {
# id
# filed {
# reasonCategory
# reasonDescription
# reportedResource {
# __typename
# ... on User {
# id
# name
# }
# ... on Post {
# id
# title
# content
# }
# ... on Comment {
# id
# content
# }
# }
# }
# }
... on FiledReport {
reportId
reasonCategory
reasonDescription
resource {
__typename
... on User {
id
name
}
... on Post {
id
title
content
}
... on Comment {
id
content
}
}
}
@ -280,21 +301,17 @@ describe('given some notifications', () => {
read: true,
reason: 'filed_report_on_resource',
from: {
__typename: 'Report',
id: 'reportOnPost',
filed: [
{
reasonCategory: 'other',
reasonDescription:
"This shouldn't be shown to anybody else! It's my private thing!",
reportedResource: {
__typename: 'Post',
id: 'p4',
title: 'Bad Post',
content: 'I am bad content !!!',
},
},
],
__typename: 'FiledReport',
reportId: 'reportOnPost',
reasonCategory: 'other',
reasonDescription:
"This shouldn't be shown to anybody else! It's my private thing!",
resource: {
__typename: 'Post',
id: 'p4',
title: 'Bad Post',
content: 'I am bad content !!!',
},
},
},
{
@ -303,19 +320,15 @@ describe('given some notifications', () => {
read: false,
reason: 'filed_report_on_resource',
from: {
__typename: 'Report',
id: 'reportOnUser',
filed: [
{
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me with bigoted remarks!',
reportedResource: {
__typename: 'User',
id: 'badWomen',
name: 'Mrs. Badwomen',
},
},
],
__typename: 'FiledReport',
reportId: 'reportOnUser',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me with bigoted remarks!',
resource: {
__typename: 'User',
id: 'badWomen',
name: 'Mrs. Badwomen',
},
},
},
{
@ -324,20 +337,16 @@ describe('given some notifications', () => {
read: false,
reason: 'filed_report_on_resource',
from: {
__typename: 'Report',
id: 'reportOnComment',
filed: [
{
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me!',
reportedResource: {
__typename: 'Comment',
id: 'c4',
content:
'I am harassing content in a harassing comment to a bad post !!!',
},
},
],
__typename: 'FiledReport',
reportId: 'reportOnComment',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me!',
resource: {
__typename: 'Comment',
id: 'c4',
content:
'I am harassing content in a harassing comment to a bad post !!!',
},
},
},
expect.objectContaining({
@ -398,19 +407,15 @@ describe('given some notifications', () => {
read: false,
reason: 'filed_report_on_resource',
from: {
__typename: 'Report',
id: 'reportOnUser',
filed: [
{
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me with bigoted remarks!',
reportedResource: {
__typename: 'User',
id: 'badWomen',
name: 'Mrs. Badwomen',
},
},
],
__typename: 'FiledReport',
reportId: 'reportOnUser',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me with bigoted remarks!',
resource: {
__typename: 'User',
id: 'badWomen',
name: 'Mrs. Badwomen',
},
},
},
{
@ -419,20 +424,16 @@ describe('given some notifications', () => {
read: false,
reason: 'filed_report_on_resource',
from: {
__typename: 'Report',
id: 'reportOnComment',
filed: [
{
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me!',
reportedResource: {
__typename: 'Comment',
id: 'c4',
content:
'I am harassing content in a harassing comment to a bad post !!!',
},
},
],
__typename: 'FiledReport',
reportId: 'reportOnComment',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me!',
resource: {
__typename: 'Comment',
id: 'c4',
content:
'I am harassing content in a harassing comment to a bad post !!!',
},
},
},
{
@ -648,8 +649,8 @@ describe('given some notifications', () => {
createdAt: '2020-01-14T12:33:48.651Z',
read: true,
from: {
__typename: 'Report',
id: 'reportOnComment',
__typename: 'FiledReport',
reportId: 'reportOnComment',
},
},
},

View File

@ -19,10 +19,10 @@ enum ReasonCategory {
}
type FiledReport {
reportId: ID!
createdAt: String!
reasonCategory: ReasonCategory!
reasonDescription: String!
reportId: ID!
resource: ReportedResource!
}

View File

@ -8,7 +8,8 @@ type NOTIFIED {
to: User!
}
union NotificationSource = Post | Comment | Report
# Wolle union NotificationSource = Post | Comment | Report
union NotificationSource = Post | Comment | FiledReport
enum NotificationOrdering {
createdAt_asc

View File

@ -1,7 +1,6 @@
import gql from 'graphql-tag'
export const reportsListQuery = () => {
// no limit for the moment like before: "reports(first: 20, orderBy: createdAt_desc)"
return gql`
query(
$orderBy: ReportOrdering