mirror of
https://github.com/flarum/framework.git
synced 2025-02-21 08:39:25 +08:00
perf: optimize querying post index (#4178)
This commit is contained in:
parent
6b31a47f05
commit
55cd0850c7
@ -129,16 +129,16 @@ class PostResource extends AbstractDatabaseResource
|
|||||||
$sort = $defaultExtracts['sort'];
|
$sort = $defaultExtracts['sort'];
|
||||||
$filter = $defaultExtracts['filter'];
|
$filter = $defaultExtracts['filter'];
|
||||||
|
|
||||||
if (count($filter) > 1 || ! isset($filter['discussion']) || $sort) {
|
if (count($filter) > 1 || ! isset($filter['discussion']) || ($sort && $sort !== ['number' => 'asc'])) {
|
||||||
throw new BadRequestException(
|
throw new BadRequestException(
|
||||||
'You can only use page[near] with filter[discussion] and the default sort order'
|
'You can only use page[near] with filter[discussion] and the default sort order'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$limit = $defaultExtracts['limit'];
|
$limit = $defaultExtracts['limit'];
|
||||||
$offset = $this->posts->getIndexForNumber((int) $filter['discussion'], $near, $context->getActor());
|
$index = $this->posts->getIndexForNumber((int) $filter['discussion'], $near, $context->getActor());
|
||||||
|
|
||||||
return max(0, $offset - $limit / 2);
|
return max(0, $index - $limit / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $defaultExtracts['offset'];
|
return $defaultExtracts['offset'];
|
||||||
@ -150,6 +150,7 @@ class PostResource extends AbstractDatabaseResource
|
|||||||
'hiddenUser',
|
'hiddenUser',
|
||||||
'discussion'
|
'discussion'
|
||||||
])
|
])
|
||||||
|
->defaultSort('number')
|
||||||
->paginate(static::$defaultLimit),
|
->paginate(static::$defaultLimit),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -85,23 +85,14 @@ class PostRepository
|
|||||||
*/
|
*/
|
||||||
public function getIndexForNumber(int $discussionId, int $number, ?User $actor = null): int
|
public function getIndexForNumber(int $discussionId, int $number, ?User $actor = null): int
|
||||||
{
|
{
|
||||||
if (! ($discussion = Discussion::find($discussionId))) {
|
if (! ($discussion = Discussion::query()->find($discussionId))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = $discussion->posts()
|
$query = $discussion->posts()
|
||||||
->whereVisibleTo($actor)
|
->whereVisibleTo($actor)
|
||||||
->where('created_at', '<', function ($query) use ($discussionId, $number) {
|
->where('number', '<=', $number)
|
||||||
$query->select('created_at')
|
->orderBy('number');
|
||||||
->from('posts')
|
|
||||||
->where('discussion_id', $discussionId)
|
|
||||||
->whereNotNull('number')
|
|
||||||
->take(1)
|
|
||||||
|
|
||||||
// We don't add $number as a binding because for some
|
|
||||||
// reason doing so makes the bindings go out of order.
|
|
||||||
->orderByRaw('ABS(CAST(number AS SIGNED) - '.(int) $number.')');
|
|
||||||
});
|
|
||||||
|
|
||||||
return $query->count();
|
return $query->count();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user