【问题标题】:Laravel eloquent complex search query questionLaravel 雄辩的复杂搜索查询问题
【发布时间】: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.

【问题讨论】:

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

标签: laravel search eloquent relationship


【解决方案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);
}

【讨论】:

    猜你喜欢
    • 2020-03-19
    • 1970-01-01
    • 2014-01-16
    • 2017-02-17
    • 1970-01-01
    • 2021-05-12
    • 2018-01-26
    • 2021-07-23
    相关资源
    最近更新 更多