dpa31905 2015-06-03 18:35
浏览 48
已采纳

Laravel搜索查询 - “OR”和“AND”的SQL排序破坏了foreach循环查询

I am having problems with my search function working properly. Currently, I have a search form with two radio buttons('keywords' and 'exact') and depending on what they have selected, it should search the database for the given array of strings or single string(both the title AND description together SHOULD contain all of the searched keywords). The issue arises when the user searches via keywords (a bunch of single word strings). Presently when i fetch the string from the form, I explode it and then run a foreach loop through it, however, it ends up messing up due to SQL's ordering of 'OR' and 'AND' operators.

For instance, a search value of search_value=black+darker would $query->toSql() to

"select * from `animes` where `description` like ? or `name` like ? and `description` like ? or `name` like ?"

However, SQL reads it as

"select * from `animes` where (`description` like ?) or (`name` like ? and `description` like ?) or (`name` like ?)"

Here is my code(ignore anything related to 'genre' as that part works correctly as expected):

public function searchAnimes(SearchRequest $request)
{
    if($request->search_type == 'keyword')
    {
        $animeSearchValues = explode(' ', Input::get('search_value'));
    }
    elseif($request->search_type == 'exact')
    {
        $animeSearchValues[0] = Input::get('search_value');
    }
    else
    {
        return redirect('animes');
    }
    $genres = $request->name;
    $query = Anime::query();

    if(isset($animeSearchValues) && strlen(Input::get('search_value')) >= 3)
    {
        foreach($animeSearchValues as $animeSearchValue)
        {
            $query->where('description', 'like', '%'.$animeSearchValue.'%')
                  ->orWhere('name', 'like', '%'.$animeSearchValue.'%');
        }

        if(isset($genres))
        {
            foreach ($genres as $genre)
            {
                $query->whereHas('genres', function ($f) use ($genre)
                {
                    $f->where('slug', $genre);
                });
            }
        }
        $animeResults = $query->orderBy('name')->paginate(10);
        return view('animes.results', compact('animeResults'));
    }
}

The only solution I have been able to think of is to take both the title and description and merge them into a single string and then search through it for each individual keyword, however, that method seems to be too jerry-rigged or nonstandard. Also, keep in mind, I need the entire thing in a single query builder as so I may display the results with pagination.

Thanks.

  • 写回答

2条回答 默认 最新

  • douti0687 2015-06-03 18:48
    关注

    Is this what you wanted? This searches for everything that has each keyword in either title or description.

    foreach($animeSearchValues as $animeSearchValue){
        $query->where(function ($q) use ($animeSearchValue){
            $q->where('description', 'like', '%'.$animeSearchValue.'%')
                ->orWhere('name', 'like', '%'.$animeSearchValue.'%');
        });
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 2024-五一综合模拟赛
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭