返回

如何优化查询以从视图列表中获取书签帖子

php

精简查询:获取特定视图列表中的书签帖子

问题

你想获取属于特定视图列表的所有已书签帖子的集合。最初的查询有点冗长,需要嵌套多个回调。

方法

1. 直接查询

优化后的查询如下:

$posts = Post::whereHas('bookmark', function ($query) use ($viewlist) {
    $query->where('bookmarkable_type', Post::class)
        ->whereHas('collections', function ($query) use ($viewlist) {
            $query->where('id', $viewlist->id);
        });
})->orderByDesc('bookmark_collection.created_at')->paginate();

此查询直接使用 whereHas 约束,指定 bookmarkable_typePost,并在 collections 表上嵌套另一个 whereHas 约束,以过滤属于指定视图列表的书签。

2. BookmarkedPosts 方法

为了进一步精简语法,可以创建 bookmarkedPosts 方法:

class User {
    public function bookmarkedPosts() {
        return $this->hasManyThrough(
            Post::class,
            Bookmark::class,
            'user_id',
            'bookmarkable_id',
            'id',
            'bookmarkable_id'
        )->where('bookmarkable_type', Post::class)->latest('bookmark.created_at');
    }
}

此方法允许你使用以下更简单的代码获取书签帖子:

$user = User::find(1);
$posts = $user->bookmarkedPosts()->paginate();

其他提示

  • 考虑使用 Eloquent 的 eager loading,一次性获取关联模型。
  • 分解查询链以提高可读性。
  • 确保使用正确的联接类型(内联接或外联接)。

结论

优化后的查询和 bookmarkedPosts 方法提供了更简洁、更有效的获取特定视图列表中书签帖子的方式。这些技术可以改善查询性能并提高代码可维护性。

常见问题解答

1. 如何在查询中过滤其他条件?

可以在 whereHas 约束内部添加额外的 where 条件,以根据需要过滤结果。

2. 如何处理多个视图列表?

可以使用 whereIn 约束处理多个视图列表。

3. 如何在 bookmarkedPosts 方法中指定视图列表?

可以在方法中添加一个参数来指定视图列表,或者使用 Eloquent 的动态作用域。

4. 如何排除已删除的帖子?

可以在 whereHas 约束中使用 whereNull 条件,排除 deleted_at 字段不为 null 的帖子。

5. 如何按书签创建日期对结果进行排序?

orderByDesc 约束中指定 bookmark.created_at 字段,以按书签创建日期降序排序。