-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve notification query performance by reducing db calls #2470
Changes from all commits
b2ccc1b
3beef5e
deefc4e
12236c9
0a50a02
4f0df2f
cc7cd6b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import Debug from 'debug' | ||
const debugCypher = Debug('human-connection:neo4j:cypher') | ||
const debugStats = Debug('human-connection:neo4j:stats') | ||
|
||
export default function log(response) { | ||
const { statement, counters, resultConsumedAfter, resultAvailableAfter } = response.summary | ||
const { text, parameters } = statement | ||
debugCypher('%s', text) | ||
debugCypher('%o', parameters) | ||
debugStats('%o', counters) | ||
debugStats('%o', { | ||
resultConsumedAfter: resultConsumedAfter.toNumber(), | ||
resultAvailableAfter: resultAvailableAfter.toNumber(), | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
import log from './helpers/databaseLogger' | ||
|
||
const transformReturnType = record => { | ||
return { | ||
...record.get('report').properties, | ||
|
@@ -11,12 +13,11 @@ const transformReturnType = record => { | |
export default { | ||
Mutation: { | ||
fileReport: async (_parent, params, context, _resolveInfo) => { | ||
let createdRelationshipWithNestedAttributes | ||
const { resourceId, reasonCategory, reasonDescription } = params | ||
const { driver, user } = context | ||
const session = driver.session() | ||
const reportWriteTxResultPromise = session.writeTransaction(async txc => { | ||
const reportTransactionResponse = await txc.run( | ||
const reportWriteTxResultPromise = session.writeTransaction(async transaction => { | ||
const reportTransactionResponse = await transaction.run( | ||
` | ||
MATCH (submitter:User {id: $submitterId}) | ||
MATCH (resource {id: $resourceId}) | ||
|
@@ -36,23 +37,23 @@ export default { | |
reasonDescription, | ||
}, | ||
) | ||
log(reportTransactionResponse) | ||
return reportTransactionResponse.records.map(transformReturnType) | ||
}) | ||
try { | ||
const txResult = await reportWriteTxResultPromise | ||
if (!txResult[0]) return null | ||
createdRelationshipWithNestedAttributes = txResult[0] | ||
const [createdRelationshipWithNestedAttributes] = await reportWriteTxResultPromise | ||
if (!createdRelationshipWithNestedAttributes) return null | ||
return createdRelationshipWithNestedAttributes | ||
} finally { | ||
session.close() | ||
} | ||
return createdRelationshipWithNestedAttributes | ||
}, | ||
}, | ||
Query: { | ||
reports: async (_parent, params, context, _resolveInfo) => { | ||
const { driver } = context | ||
const session = driver.session() | ||
let reports, orderByClause, filterClause | ||
let orderByClause, filterClause | ||
switch (params.orderBy) { | ||
case 'createdAt_asc': | ||
orderByClause = 'ORDER BY report.createdAt ASC' | ||
|
@@ -81,8 +82,8 @@ export default { | |
params.offset && typeof params.offset === 'number' ? `SKIP ${params.offset}` : '' | ||
const limit = params.first && typeof params.first === 'number' ? `LIMIT ${params.first}` : '' | ||
|
||
const reportReadTxPromise = session.readTransaction(async tx => { | ||
const allReportsTransactionResponse = await tx.run( | ||
const reportReadTxPromise = session.readTransaction(async transaction => { | ||
const allReportsTransactionResponse = await transaction.run( | ||
` | ||
MATCH (report:Report)-[:BELONGS_TO]->(resource) | ||
WHERE (resource:User OR resource:Post OR resource:Comment) | ||
|
@@ -100,16 +101,15 @@ export default { | |
${offset} ${limit} | ||
`, | ||
) | ||
log(allReportsTransactionResponse) | ||
return allReportsTransactionResponse.records.map(record => record.get('report')) | ||
}) | ||
try { | ||
const txResult = await reportReadTxPromise | ||
if (!txResult[0]) return null | ||
reports = txResult | ||
const reports = await reportReadTxPromise | ||
return reports | ||
} finally { | ||
session.close() | ||
} | ||
return reports | ||
}, | ||
}, | ||
Report: { | ||
|
@@ -118,23 +118,23 @@ export default { | |
const session = context.driver.session() | ||
const { id } = parent | ||
let filed | ||
const readTxPromise = session.readTransaction(async tx => { | ||
const allReportsTransactionResponse = await tx.run( | ||
const readTxPromise = session.readTransaction(async transaction => { | ||
const filedReportsTransactionResponse = await transaction.run( | ||
` | ||
MATCH (submitter:User)-[filed:FILED]->(report:Report {id: $id}) | ||
RETURN filed, submitter | ||
MATCH (submitter:User)-[filed:FILED]->(report:Report {id: $id}) | ||
RETURN filed, submitter | ||
`, | ||
{ id }, | ||
) | ||
return allReportsTransactionResponse.records.map(record => ({ | ||
log(filedReportsTransactionResponse) | ||
return filedReportsTransactionResponse.records.map(record => ({ | ||
submitter: record.get('submitter').properties, | ||
filed: record.get('filed').properties, | ||
})) | ||
}) | ||
try { | ||
const txResult = await readTxPromise | ||
if (!txResult[0]) return null | ||
filed = txResult.map(reportedRecord => { | ||
const filedReports = await readTxPromise | ||
filed = filedReports.map(reportedRecord => { | ||
const { submitter, filed } = reportedRecord | ||
const relationshipWithNestedAttributes = { | ||
...filed, | ||
|
@@ -152,23 +152,24 @@ export default { | |
const session = context.driver.session() | ||
const { id } = parent | ||
let reviewed | ||
const readTxPromise = session.readTransaction(async tx => { | ||
const allReportsTransactionResponse = await tx.run( | ||
const readTxPromise = session.readTransaction(async transaction => { | ||
const reviewedReportsTransactionResponse = await transaction.run( | ||
` | ||
MATCH (resource)<-[:BELONGS_TO]-(report:Report {id: $id})<-[review:REVIEWED]-(moderator:User) | ||
RETURN moderator, review | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@@ -153,14 +155,14 @@ export default {
const { id } = parent
let reviewed
const readTxPromise = session.readTransaction(async tx => {
- const allReportsTransactionResponse = await tx.run(
- `
- MATCH (resource)<-[:BELONGS_TO]-(report:Report {id: $id})<-[review:REVIEWED]-(moderator:User)
- RETURN moderator, review
- ORDER BY report.updatedAt DESC, review.updatedAt DESC
- `,
- { id },
- )
+ const cypher = `
+ MATCH (resource)<-[:BELONGS_TO]-(report:Report {id: $id})<-[review:REVIEWED]-(moderator:User)
+ RETURN moderator, review
+ ORDER BY report.updatedAt DESC, review.updatedAt DESC
+ `
+ const params = { id }
+ const allReportsTransactionResponse = await tx.run(cypher, params)
+ log(allReportsTransactionResponse) same question as your other There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I want to see the database calls being made when I set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
that part, I get... I don't understand how why that needed so much refactoring
so I'm assuming the wildcard needs to be replaced by something, but what? Ahh There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On fish shell: env DEBUG="human-connection:neo4j:*" yarn run dev if you don't escape the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
great thanks @roschaefer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ahhh, ok here are the result of running a
|
||
ORDER BY report.updatedAt DESC, review.updatedAt DESC | ||
`, | ||
{ id }, | ||
) | ||
return allReportsTransactionResponse.records.map(record => ({ | ||
log(reviewedReportsTransactionResponse) | ||
return reviewedReportsTransactionResponse.records.map(record => ({ | ||
review: record.get('review').properties, | ||
moderator: record.get('moderator').properties, | ||
})) | ||
}) | ||
try { | ||
const txResult = await readTxPromise | ||
reviewed = txResult.map(reportedRecord => { | ||
const reviewedReports = await readTxPromise | ||
reviewed = reviewedReports.map(reportedRecord => { | ||
const { review, moderator } = reportedRecord | ||
const relationshipWithNestedAttributes = { | ||
...review, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How could
reports
ever be not an array?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we run into an error I would prefer HTTP 500
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, revert it to return null?