从 Eloquent 集合中删除不匹配的条件记录

Posted

技术标签:

【中文标题】从 Eloquent 集合中删除不匹配的条件记录【英文标题】:Remove unmatched criteria records from Eloquent collection 【发布时间】:2021-07-15 08:58:58 【问题描述】:

我在使用 Eloquent Eager Loading 时遇到了一些问题。我添加了whereHas 以删除博客不符合评论条件但评论仍然返回空数组。我的意图是将其从 json 记录中完全删除。

怎样才能彻底去掉不符合我条件的json数据链?

我当前的代码:

User::select("id", "name", "email")
    ->with(['blog', 'blog.author', 'blog.comments' => function ($query) 
        $query->where('comment', 'John is here');
    , 'blog.comments.owner'])
    ->whereHas('blog.comments', function ($query) 
        $query->where('comment', 'John is Here');
    )
    ->get();

我当前的 json 输出是:


    "id": 1,
    "name": "John Smith",
    "email": "john.smith@hotmail.com",
    "blog": [
        
            "id": 1,
            "created_at": "2021-04-09T18:08:06.000000Z",
            "updated_at": "2021-04-09T10:33:03.000000Z",
            "title": "First Blog",
            "description": "Awesome",
            "users_id": 1,
            "cover": null,
            "author": 
                "id": 1,
                "name": "John Smith",
                "email": "john.smith@hotmail.com",
                "email_verified_at": null,
                "created_at": "2021-04-08T13:29:13.000000Z",
                "updated_at": "2021-04-08T13:29:13.000000Z",
                "role": 0
            ,
            "comments": [
                
                    "id": 1,
                    "comment": "John is here",
                    "blog_id": 1,
                    "user_id": 1,
                    "created_at": null,
                    "updated_at": null,
                    "owner": 
                        "id": 1,
                        "name": "John Smith",
                        "email": "john.smith@hotmail.com",
                        "email_verified_at": null,
                        "created_at": "2021-04-08T13:29:13.000000Z",
                        "updated_at": "2021-04-08T13:29:13.000000Z",
                        "role": 0
                    
                
            ]
        ,
        
            "id": 6,
            "created_at": "2021-04-12T07:41:43.000000Z",
            "updated_at": "2021-04-12T08:01:18.000000Z",
            "title": "Second Blog",
            "description": "Awesome",
            "users_id": 1,
            "cover": "images/json_1618213303.png",
            "author": 
                "id": 1,
                "name": "John Smith",
                "email": "john.smith@hotmail.com",
                "email_verified_at": null,
                "created_at": "2021-04-08T13:29:13.000000Z",
                "updated_at": "2021-04-08T13:29:13.000000Z",
                "role": 0
            ,
            "comments": []
        
    ]

我的预期输出是:


    "id": 1,
    "name": "John Smith",
    "email": "john.smith@hotmail.com",
    "blog": [
        
            "id": 1,
            "created_at": "2021-04-09T18:08:06.000000Z",
            "updated_at": "2021-04-09T10:33:03.000000Z",
            "title": "First Blog",
            "description": "Awesome",
            "users_id": 1,
            "cover": null,
            "author": 
                "id": 1,
                "name": "John Smith",
                "email": "john.smith@hotmail.com",
                "email_verified_at": null,
                "created_at": "2021-04-08T13:29:13.000000Z",
                "updated_at": "2021-04-08T13:29:13.000000Z",
                "role": 0
            ,
            "comments": [
                
                    "id": 1,
                    "comment": "John is here",
                    "blog_id": 1,
                    "user_id": 1,
                    "created_at": null,
                    "updated_at": null,
                    "owner": 
                        "id": 1,
                        "name": "John Smith",
                        "email": "john.smith@hotmail.com",
                        "email_verified_at": null,
                        "created_at": "2021-04-08T13:29:13.000000Z",
                        "updated_at": "2021-04-08T13:29:13.000000Z",
                        "role": 0
                    
                
            ]
        
    ]

【问题讨论】:

能否将->get() 替换为->toSql() 并共享正在运行的SQL? select id, name, email from users where exists (select * from blogs where users.id = blogs.@98765433存在(从comments 中选择*,其中blogs.id = comments.blog_idcomment = ?)) 我虽然会执行内连接 这有点不合我意,我的意思是,我帮不了你太多了,对不起 【参考方案1】:

试试这个,

User::select("id", "name", "email")
    ->with([
        'blog' => function ($query) 
            $query->whereHas('comments', function ($query) 
                $query->where('comment', 'John is Here');
            );
        , 
        'blog.comments' => function ($query) 
            $query->where('comment', 'John is here');
        ,
        'blog.author',  
        'blog.comments.owner'])
    ->get();

您也应该对blog 急切加载应用约束。您的查询仅过滤 commentsblog

【讨论】:

我有一个关于 eloquent 模型的问题,我如何构建一个与 eloquent 模型合并的连接查询,但输出必须将我作为集合返回。我曾尝试使用类似 "User::join("user_role","id","=","user.role_id")" 的东西,但是当有人决定更改表名时,这可能会导致另一个问题,它可能会直接崩溃整个代码。 我建议像$user->roles 那样访问相关记录,但您首先必须定义User 模型和Role 之间的多对多roles 关系。

以上是关于从 Eloquent 集合中删除不匹配的条件记录的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent API 资源:从响应(集合)中删除“数据”键

如何更改 Eloquent 集合中结果的顺序?

删除与ag-grid中的筛选条件匹配的记录

mongoose 删除 API

雄辩的条件更新

从字符串成员的条件匹配的集合中查找对象的最快方法