【问题标题】:how can i search multiple keywords in laravel .?我如何在 laravel 中搜索多个关键字。?
【发布时间】:2018-03-27 18:28:27
【问题描述】:

这是我的控制器

 $term = $request->get('q');

 // return $request->q;

 $products = Post::whereHas('user', function($query) use($term) {
     $query->where('name', 'like', '%'.$term.'%');
 })->orWhere('tags','LIKE','%'.$term.'%')->get();
 return view('pages.search', compact('products','users'));

这适用于单关键字搜索。但我想将它用于多个关键字。像 laravel php 等。当我搜索多个值(如 abc php laravel 或其他任何值)时,请指导我,然后它应该可以工作。如果标签存在于不同的列中,例如 php 在第一列中存在,而 laravel 在下一列中,则当我搜索 php laravel 时,它应该向我显示两个列值。

【问题讨论】:

    标签: laravel search keyword


    【解决方案1】:

    过去几天我在这方面花了很多时间,这是我的解决方案。它与其他类似但不同,因此有一天它可能对某人有价值:

    我有一个发出 GET 请求的 Vue 组件,所以 $request->get('searchTerms') 来自 HTML 表单提交中的 <input name="searchTerms">

    我想让用户控制要搜索的字段,这就是为什么 $search_terms 是要搜索的列数组。

    我想要它,所以如果用户搜索“McDonalds 604”,它将过滤记录列表并为该搜索显示两个不同的匹配项。一个与business_name 匹配的“麦当劳”和一个与phone_number 的区号匹配的“604”。这将确保用户在只知道一些片段的情况下获得所有相关信息。

    目标是迭代搜索词,并使用通用公式迭代搜索字段(列),该公式可应用于任意数量的搜索词和列,在运行时动态.

            $search_fields = ['project_name', 'business_name', 'phone_number'];
            $search_terms = explode(' ', $request->get('searchTerms'));
    
            $query = Campaign::query();
            foreach ($search_terms as $term) {
                $query->orWhere(function ($query) use ($search_fields, $term) {
    
                    foreach ($search_fields as $field) {
                        $query->orWhere($field, 'LIKE', '%' . $term . '%');
                    }
                });
            }
            $filtered = $query->get();
    

    我建议阅读 Laravel 的查询文档,因为它会让您对这项任务有更好的直觉:https://laravel.com/docs/5.6/queries

    在上面的代码中,我们使用parameter grouping,如果你使用whereorWhere相比,它会改变算法的特性。

    奖金事实

    我还强烈建议您使用$query->toSql()$query->getBindings() 测试您的SQL 语句。您可以将它们放在$query->get() 的位置,以查看它生成的 SQL 语句是什么样的以及参数绑定是什么。 getBindings() 将显示?toSql() 中的值。

    【讨论】:

      【解决方案2】:

      您需要先准备 $terms 数组,然后对其进行迭代并添加 orWhere() 子句。

      我刚刚对其进行了测试,对于 whereHas() 闭包,您需要在第一个任期内使用 where() 并在其余部分使用 orWhere() 以使其正常工作:

      $posts = Post::whereHas('user', function($q) use($terms) {
              $q->where('name', 'like', '%' . $term .'%');
      
              foreach (array_slice($terms, 1) as $term) {
                  $q->orWhere('name', 'like', '%' . $term .'%');
              }
          });
      
      foreach ($terms as $term) {
          $posts->orWhere('tags', 'like', '%' . $term . '%');
      }
      
      $posts = $posts->get();
      

      如果您决定使用= 而不是like,只需使用whereIn() 而不是使用一堆orWhere() 构建查询。

      【讨论】:

      • 解析错误:语法错误,意外'foreach' (T_FOREACH)
      • foreach (array_slice($terms, 1) as $term) 在此处显示错误
      • 解析错误:语法错误,意外 ';',期待 ',' 或 ')' 再次
      • 您的代码可能有效,但我遇到了语法错误。你在哪里关闭大括号 };在第二次 foreach 之前。
      • @MuhammadHaroon 正如我所说,您需要先准备一个数组。所以,$terms 应该是一个数组或关键字。
      【解决方案3】:

      可能有更好的方法来做到这一点,例如使用 CloudSearch/Algolia,但这是一个对我们有用的解决方案:

      // Split the terms by word.
      $terms = explode(" ", request('q'));
      
      $products = Post::query()
          ->whereHas('user', function ($query) use ($terms) {
              foreach ($terms as $term) {
                  // Loop over the terms and do a search for each.
                  $query->where('name', 'like', '%' . $term . '%');
              }
          })
          ->orWhere(function ($query) use ($terms) {
              foreach ($terms as $term) {
                  $query->where('tags', 'like', '%' . $term . '%');
              }
          })
          ->get();
      

      【讨论】:

      • @AlexeyMezenin 不需要重新分配查询,或者返回它。它是一个参考。此外,这取决于您的用例,但我认为 Laravel 在您最初没有执行 where 时已经删除了执行 orWhere 的能力。
      • 我刚刚测试了它,它不起作用。你不需要重新分配查询,但你不能像你一样在循环或闭包中使用->where。因此,您需要重新分配$posts,正如我在代码中显示的那样,并构建一堆orWhere,对于whereHas() 部分,它应该是一个where 和一堆orWhere()。跨度>
      • @AlexeyMezenin 自从我上次发表评论以来,您已经更改了您的代码,以删除您在最初评论中谈论的内容,您也已删除。我的答案中显示的代码应该可以正常工作,并且可以在我们的一个生产站点中使用。
      • 是的,我已经测试了我的代码和你的代码,并通过代码进行了编辑,之后我添加了之前的评论。你的代码不行,我已经测试过了。
      • 您重新分配$query->where 是对的,但在添加多个orWhere 之后,OP 仍需要重新分配$posts(或任何变量)。跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 1970-01-01
      • 2017-09-18
      • 2013-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多