Laravel 雄辩的复杂搜索查询问题

Posted

技术标签:

【中文标题】Laravel 雄辩的复杂搜索查询问题【英文标题】:Laravel eloquent complex search query question 【发布时间】:2019-12-19 09:45:39 【问题描述】:

一直在尝试不同的方法来使用 Eloquent 对多个嵌套的多对多和 hasmany 关系执行搜索查询,但无法找到解决方案。

为了简化下面我想使用'model', 'LIKE', '%' . $request->name . '%'执行搜索的模型部分。

模型

    class Company extends Model 
        // the class properties, dates, etc...
        public function offices()
            return $this belongsToMany(Office::class);
        
    

    class Office extends Model 
        // the class properties, dates, etc...
        public function companies()
            return $this belongsToMany(Company::class);
        

        public function addresses()
            return $this belongsToMany(Address::class);
        
    

    class Address extends Model 
        // the class properties, dates, etc...
        public function offices()
            return $this belongsToMany(Office::class);
        

        public function services()
            return $this belongsToMany(Service::class);
        

        public function countries()
            return $this belongsToMany(Country::class);
        
    

    class Service extends Model 
        // the class properties, dates, etc...
        public function addresses()
            return $this belongsToMany(Address::class);
        
    

    class Country extends Model 
        // the class properties, dates, etc...
        public function addresses()
            return $this belongsToMany(Address::class);
        
    

目标是根据公司的主要模型搜索不同的模型。在伪代码中将类似于以下内容:

Company 中查找 name$request->name 或者像$request->name这样的公司 网站 或者在哪里 Office office_name $request->name地址 街道 $request->name地址 country.name $request->name 或者在哪里 Service addresses.service.name $request->name

一个公司有很多办公室 办公室有很多地址 Address 包含 Country 和 一个地址有许多服务

在所有这些中,为了简化(我可能能够推断和处理每个模型的其他字段,我将使用 name 列。例如。公司名称办事处名称地址名称服务名称 国家/地区名称

我现在拥有的是以下内容,它没有按我的需要执行搜索:

public function search(Request $request)

    $data = Company::Active()->with('offices', 'addresses', 'offices.addresses')
        ->where('company_name', 'LIKE', '%' . $request->name . '%')
        ->orWhere('company_short_description', 'LIKE', '%' . $request->name . '%')
        ->orWhere('company_long_description', 'LIKE', '%' . $request->name . '%')
        ->orWhere('company_website', 'LIKE', '%' . $request->name . '%')
        ->whereHas('offices', function ($query) use ($request) 
            $query->where('name', 'LIKE', '%' . $request->name . '%');
        )
        ->whereHas('offices.addresses', function ($query) use($request)
            $query->where('name', 'LIKE', '%' . $request->name . '%')
                ->orWhere('address_city', 'LIKE', '%' . $request->name . '%');
        )
        ->orderBy('company_name')
        ->paginate(20);

    return response()->json($data, 200);


Thank you in advance for any help or tips on the better solution to perform this broad (complex) search query with Eloquent.

【问题讨论】:

看这里:github.com/staudenmeir/eloquent-has-many-deep 我自己喜欢这种方法,它包括嵌套关系。 freek.dev/… 让它非常干净 imo 这个搜索功能是否被用于 jquery 数据表?如果是这样,您可以在视图中定义可搜索的属性,并让数据表处理其余部分。如果没有,也许您可​​以通过使用诸如filter() 之类的收集方法进行查询之后进行过滤 @IGP 没有数据表。那会更容易。即使是 rway 查询对我来说也会更容易,但在 Eloquent 中,我对嵌套关系上的这种类型的查询感到有点困惑。公司 > 办公室 > 地址 > 国家 + 服务。在原始的 mysql 中,我知道如何立即执行此操作。也会看看 dparoli 和 Robbin Bernard 的建议。 如果您在问题中进行编辑,我也许可以将原始 sql 查询转换为 eloquent/builder 格式。 【参考方案1】:

我想我可以管理查询。不确定是最好的方法还是可能需要一些优化,但我至少可以从下面的查询中得到最近似的结果集。欢迎提出改进建议:)

public function search(Request $request)

    $data = Company::Active()->with('offices', 'addresses', 'offices.addresses')
        ->where('company_name', 'LIKE', '%' . $request->name . '%')
        ->orWhere('company_short_description', 'LIKE', '%' . $request->name . '%')
        ->orWhere('company_long_description', 'LIKE', '%' . $request->name . '%')
        ->orWhere('company_website', 'LIKE', '%' . $request->name . '%')
        ->orWhereHas('offices', function ($query) use ($request) 
            $query->where('name', 'LIKE', '%' . $request->name . '%');
        )
        ->orWhereHas('offices.addresses', function ($query) use($request)
            $query->where('name', 'LIKE', '%' . $request->name . '%')
                ->orWhere('address_city', 'LIKE', '%' . $request->name . '%');
        )
        ->orWhereHas('offices.addresses.services', function ($query) use($request)
            $query->where('name', 'LIKE', '%' . $request->name . '%');
        )
        ->orderBy('company_name')
        ->paginate(20);

    return response()->json($data, 200);

【讨论】:

以上是关于Laravel 雄辩的复杂搜索查询问题的主要内容,如果未能解决你的问题,请参考以下文章

雄辩的查询构建器laravel 5.6中的未知列

带有“LIKE”语句的雄辩查询在 Laravel 6 中不起作用

Laravel 复杂的雄辩关系

雄辩给出错误,但查询在 phpmyadmin 中执行良好

Laravel 雄辩地搜索相关模型的字段

Laravel 雄辩的极限查询