【问题标题】:在模型及其关系中搜索并对结果进行分页
【发布时间】:2014-11-23 22:16:01
【问题描述】:

所以我正在使用 Laravel/MySQL 构建一个电子商务网站,我拥有的产品相关表如下:“产品”、“属性”、“分类法”和“标签”。当用户输入关键字搜索产品时,我想用一个查询搜索所有 4 个表以获得所需的产品,然后我想使用 Laravel 分页功能对结果进行分页,现在我如何在一个查询中完成?也许涉及一些连接?

这里是我的数据库表的关系,至于我的模型,是这样定义的:

class Product extends Eloquent {
    ...
    public function taxonomies() {
        return $this->belongsToMany('Taxonomy', 'product_taxonomy', 'product_id', 'taxonomy_id');
    }
    ...
    // Same goes for attributes and labels
    public function reviews() {
        return $this->hasMany('Review', 'product_id');
    }
}

【问题讨论】:

  • 向我们展示您的尝试,我们将帮助您找到解决问题的方法
  • 你可以在你的 Eloquent 模型中定义你的关系,然后在你调用它时延迟加载关系。如果您发布您的表格结构,我们绝对可以提供更好的帮助。

标签: mysql search laravel laravel-4 eloquent


【解决方案1】:

也许你想要这样的东西:

$products = Product::where('name', 'LIKE ', '%' . $keyword . '%');

$products = $products->orWhereHas('attributes',
    function ($query) use ($keyword) {
        $query->where('name', 'LIKE ', '%' . $keyword . '%');
    }
);
$products = $products->orWhereHas('taxonomies',
    function ($query) use ($keyword) {
        $query->where('name', 'LIKE ', '%' . $keyword . '%');
    }
);
$products = $products->orWhereHas('tags', 
    function ($query) use ($keyword) {
        $query->where('name', 'LIKE ', '%' . $keyword . '%');
    }
);


$products = $products->paginate(10);

现在您查看产品名称和关系名称(标签、分类法和属性)并对 10 个产品进行分页。

【讨论】:

  • 正确!正是我需要的。模型和关系都设置好了,这个就像一个魅力!非常感谢。
  • @dulan 为什么你接受其他答案呢?您只能接受所有答案中的一个答案。我看到您已经两次更改接受的答案
  • 嗯,对不起这里的菜鸟...下次会注意,认为这些答案很接近并感谢他们的帮助...
  • @dulan 所以决定哪个是您问题的正确解决方案,并接受这个而不是其他的。如果他们有类似的问题,它也将有助于将来的其他用户
  • 而不是写like查询如果你写match against查询会快得多。
【解决方案2】:

你可以这样试试

$data = DB::table('products')
->join('attributes', 'products.attributes_id', '=', 'attributes.id')
->join('taxonomies', 'products.taxonomies_id', '=', 'taxonomies.id')
->join('tags', 'host_vulnerabilities.tags_id', '=', 'tags.id')
->where('products.id', '=', $id)
->select('products.id', 'attributes.name') //all required fields
->paginate(15);

我刚刚添加了示例示例。请根据您的要求更新代码

【讨论】:

  • 这是我需要的,但是很抱歉我忘了提到产品和分类是多对多的关系,所以我使用了像 product_taxonomy 这样的数据透视表,而不是将 taxonomy_id 作为产品表中的外键,属性和标签也是如此,有什么想法吗?
  • 然后创建模型来获取数据,您可以为此使用 belongsToMany 关系检查此文档。 laravel.com/docs/4.2/eloquent
  • 所以我快速浏览了文档,如果我没记错的话,我猜我应该使用如下查询关系: $products = Product::whereHas('taxonomies', function($q) {$ q->where('taxonomy_name', 'like', '%' . $keyword .'%');}->whereHas('tags', function($q) {$q->where('tag_name', 'like', '%' . $keyword . '%');})->paginate(10); yes?no?
  • 最好的方法是实现 laravel 模型。或者您可以直接使用 raw() 函数并编写 sql 查询然后使用 paginate 函数。
  • 我确实实现了 laravel 模型及其所有关系,您能告诉我我应该如何在 Laravel 中编写查询吗?或者,如果问得太多,您能否指出文档的哪个部分恰好属于我的情况,您之前放置链接的文档?谢谢。
【解决方案3】:

为此使用UNION

SELECT product_id, product name FROM Products WHERE keyword = 'my_keyword' UNION 
SELECT product_id, product name FROM Attributes WHERE keyword = 'my_keyword' UNION
..... Same for other tables

此外,它将过滤掉重复的结果,因为UNIONUNION DISTINCT 一样工作。但是如果你给我们提供一个schema或者一些db结构,可以提供更好的解决方案。

对于 Laravel,这可能有效,您可以创建一个视图并查询该视图而不是实际的表,或者手动创建您的分页器:

$page = Input::get('page', 1);
$paginate = 10;
$w1 = 'my_keyword';

$first = DB::table('products')->where('attribute', 'like', '"%'.$w1.'%"');
$second = DB::table('attributes')->where('attribute', 'like', '"%'.$w1.'%"');
$third = DB::table('taxonomies')->where('attribute', 'like', '"%'.$w1.'%"');
$fourth = DB::table('tags')->where('attribute', 'like', '"%'.$w1.'%"');

$union1 = $first->union($second);
$union2 = $third->union($union1);
$union3 = $fourth->union($union2);
$union3->get();

$slice = array_slice($union3, $paginate * ($page - 1), $paginate);
$result = Paginator::make($slice, count($union3), $paginate);

return View::make('yourView',compact('result'));

【讨论】:

  • 感谢您的快速回答,我确信这个可行,但我更喜欢 Laravel 上下文解决方法。
  • 如果我做对了,这不是一次获取所有可能的产品吗?如果是这样,那么我认为分页失去了意义?
  • 请让我知道您对我的答案投反对票的问题,以便我改进我的答案并学习。
  • 没什么错,我只是对这里的赞成/反对规则感到困惑,Marcin Nabiałek 告诉我我只能接受一个答案,所以...
  • 没关系老兄,我很高兴能帮到你。
猜你喜欢
  • 1970-01-01
  • 2015-04-05
  • 2012-12-01
  • 2014-01-25
  • 1970-01-01
  • 2019-03-15
  • 2021-05-22
  • 2016-06-13
相关资源
最近更新 更多