Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Framasoft
PeerTube
PeerTube
Commits
0b96a0fb
Verified
Commit
0b96a0fb
authored
Jan 12, 2023
by
Chocobozzz
Browse files
Optimize again comments list sql query
parent
3f3530c3
Changes
3
Hide whitespace changes
Inline
Side-by-side
server/models/shared/sort.ts
View file @
0b96a0fb
...
...
@@ -49,7 +49,7 @@ function getCommentSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]):
if
(
field
===
'
totalReplies
'
)
{
return
[
[
Sequelize
.
literal
(
'
"
totalReplies
"
'
)
,
direction
],
[
'
totalReplies
'
,
direction
],
lastSort
]
}
...
...
server/models/video/sql/comment/video-comment-list-query-builder.ts
View file @
0b96a0fb
...
...
@@ -44,6 +44,7 @@ export class VideoCommentListQueryBuilder extends AbstractRunQuery {
private
innerSelect
=
''
private
innerJoins
=
''
private
innerLateralJoins
=
''
private
innerWhere
=
''
private
readonly
built
=
{
...
...
@@ -59,6 +60,10 @@ export class VideoCommentListQueryBuilder extends AbstractRunQuery {
private
readonly
options
:
ListVideoCommentsOptions
)
{
super
(
sequelize
)
if
(
this
.
options
.
includeReplyCounters
&&
!
this
.
options
.
videoId
)
{
throw
new
Error
(
'
Cannot include reply counters without videoId
'
)
}
}
async
listComments
<
T
extends
Model
>
()
{
...
...
@@ -97,6 +102,7 @@ export class VideoCommentListQueryBuilder extends AbstractRunQuery {
this
.
innerQuery
=
`
${
this
.
innerSelect
}
`
+
`FROM "videoComment" AS "VideoCommentModel" `
+
`
${
this
.
innerJoins
}
`
+
`
${
this
.
innerLateralJoins
}
`
+
`
${
this
.
innerWhere
}
`
+
`
${
this
.
getOrder
()}
`
+
`
${
this
.
getInnerLimit
()}
`
...
...
@@ -284,11 +290,6 @@ export class VideoCommentListQueryBuilder extends AbstractRunQuery {
toSelect
.
push
(
this
.
tableAttributes
.
getAvatarAttributes
())
}
if
(
this
.
options
.
includeReplyCounters
===
true
)
{
toSelect
.
push
(
this
.
getTotalRepliesSelect
())
toSelect
.
push
(
this
.
getAuthorTotalRepliesSelect
())
}
this
.
select
=
this
.
buildSelect
(
toSelect
)
}
...
...
@@ -307,6 +308,14 @@ export class VideoCommentListQueryBuilder extends AbstractRunQuery {
])
}
if
(
this
.
options
.
includeReplyCounters
===
true
)
{
this
.
buildTotalRepliesSelect
()
this
.
buildAuthorTotalRepliesSelect
()
toSelect
.
push
(
'
"totalRepliesFromVideoAuthor"."count" AS "totalRepliesFromVideoAuthor"
'
)
toSelect
.
push
(
'
"totalReplies"."count" AS "totalReplies"
'
)
}
this
.
innerSelect
=
this
.
buildSelect
(
toSelect
)
}
...
...
@@ -344,26 +353,32 @@ export class VideoCommentListQueryBuilder extends AbstractRunQuery {
// ---------------------------------------------------------------------------
private
get
TotalRepliesSelect
()
{
private
build
TotalRepliesSelect
()
{
const
blockWhereString
=
this
.
getBlockWhere
(
'
replies
'
,
'
videoChannel
'
).
join
(
'
AND
'
)
return
`(`
+
`SELECT COUNT("replies"."id") FROM "videoComment" AS "replies" `
+
`LEFT JOIN "video" ON "video"."id" = "replies"."videoId" `
+
// Help the planner by providing videoId that should filter out many comments
this
.
replacements
.
videoId
=
this
.
options
.
videoId
this
.
innerLateralJoins
+=
`LEFT JOIN LATERAL (`
+
`SELECT COUNT("replies"."id") AS "count" FROM "videoComment" AS "replies" `
+
`INNER JOIN "video" ON "video"."id" = "replies"."videoId" AND "replies"."videoId" = :videoId `
+
`LEFT JOIN "videoChannel" ON "video"."channelId" = "videoChannel"."id" `
+
`WHERE "replies"."originCommentId" = "VideoCommentModel"."id" `
+
`AND "deletedAt" IS NULL `
+
`AND
${
blockWhereString
}
`
+
`)
AS
"totalReplies"`
`) "totalReplies"
ON TRUE
`
}
private
getAuthorTotalRepliesSelect
()
{
return
`(`
+
`SELECT COUNT("replies"."id") FROM "videoComment" AS "replies" `
+
`INNER JOIN "video" ON "video"."id" = "replies"."videoId" `
+
private
buildAuthorTotalRepliesSelect
()
{
// Help the planner by providing videoId that should filter out many comments
this
.
replacements
.
videoId
=
this
.
options
.
videoId
this
.
innerLateralJoins
+=
`LEFT JOIN LATERAL (`
+
`SELECT COUNT("replies"."id") AS "count" FROM "videoComment" AS "replies" `
+
`INNER JOIN "video" ON "video"."id" = "replies"."videoId" AND "replies"."videoId" = :videoId `
+
`INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" `
+
`WHERE "replies"."originCommentId" = "VideoCommentModel"."id" AND "replies"."accountId" = "videoChannel"."accountId"`
+
`)
AS
"totalRepliesFromVideoAuthor"`
`) "totalRepliesFromVideoAuthor"
ON TRUE
`
}
private
getOrder
()
{
...
...
server/tests/api/videos/video-comments.ts
View file @
0b96a0fb
...
...
@@ -169,6 +169,13 @@ describe('Test video comments', function () {
expect
(
body
.
data
[
2
].
totalReplies
).
to
.
equal
(
0
)
})
it
(
'
Should list the and sort them by total replies
'
,
async
function
()
{
const
body
=
await
command
.
listThreads
({
videoId
:
videoUUID
,
sort
:
'
totalReplies
'
})
expect
(
body
.
data
[
2
].
text
).
to
.
equal
(
'
my super first comment
'
)
expect
(
body
.
data
[
2
].
totalReplies
).
to
.
equal
(
3
)
})
it
(
'
Should delete a reply
'
,
async
function
()
{
await
command
.
delete
({
videoId
,
commentId
:
replyToDeleteId
})
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment