[{"data":1,"prerenderedAt":369},["ShallowReactive",2],{"writing-pragmatic-and-lightweight-search-for-laravel-models":3},{"id":4,"title":5,"body":6,"category":354,"date":355,"description":356,"excerpt":357,"extension":358,"image":359,"keywords":360,"meta":361,"navigation":212,"path":362,"readingTime":363,"seo":364,"slug":365,"stem":366,"tags":367,"__hash__":368},"blog\u002Fblog\u002Fpragmatic-and-lightweight-search-for-laravel-models.md","Pragmatic and lightweight search for Laravel Models",{"type":7,"value":8,"toc":350},"minimark",[9,30,38,68,71,76,86,109,120,140,143,162,169,225,239,242,261,265,278,324,343,346],[10,11,12,13,20,21,25,26,29],"p",{},"You can always install ",[14,15,19],"a",{"href":16,"rel":17},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F5.9\u002Fscout",[18],"nofollow","Laravel Scout"," and use some of its engines for ",[22,23,24],"strong",{},"searching",". However sometimes we don't need that heavy-on-server search, so we can use this simple approach for ",[22,27,28],{},"searching data"," in your databases.",[10,31,32,33,37],{},"If you want to search for some data in the database, for example search for some ",[34,35,36],"em",{},"Users"," by their username or email, you can perform a search using Eloquent like this:",[39,40,45],"pre",{"className":41,"code":42,"language":43,"meta":44,"style":44},"language-php shiki shiki-themes github-light github-dark","$users = User::where('username', 'LIKE', \"%{$username}%\")\n  ->orWhere('email', 'LIKE', \"%{$email}%\")\n  ->get();\n","php","",[46,47,48,56,62],"code",{"__ignoreMap":44},[49,50,53],"span",{"class":51,"line":52},"line",1,[49,54,55],{},"$users = User::where('username', 'LIKE', \"%{$username}%\")\n",[49,57,59],{"class":51,"line":58},2,[49,60,61],{},"  ->orWhere('email', 'LIKE', \"%{$email}%\")\n",[49,63,65],{"class":51,"line":64},3,[49,66,67],{},"  ->get();\n",[10,69,70],{},"There are two ways to do this, so I am going to cover both of them now and explain when to use which approach.",[72,73,75],"h2",{"id":74},"first-approach-using-macros","First approach: Using macros",[10,77,78,79],{},"This approach is good when you want to include the search across all of your models, and not just one of them. Using macros you can ",[34,80,81,82,85],{},"simply create a function that will give you the possibility of chaining ",[22,83,84],{},"Eloquent query"," into one function and calling it anywhere within your application.",[10,87,88,89,92,93,96,97,100,101,104,105,108],{},"If you want to define a macro, you have to do it in a ",[22,90,91],{},"service provider",". You can either add the macro to ",[46,94,95],{},"AppServiceProvider.php"," or create a new service provider called (for example) ",[46,98,99],{},"MacroServiceProvider.php"," and place the macro in the ",[46,102,103],{},"boot"," method of the service provider. If you create a new service provider, don't forget to add it to the service providers array in ",[46,106,107],{},"config\u002Fapp.php"," .",[10,110,111,112,115,116,119],{},"To define a macro, you simply use the ",[22,113,114],{},"macro static method"," on the class you want to define the macro to. We need to define a macro for the ",[22,117,118],{},"Eloquent class",", so we can extend it like this (in the boot method of the service provider):",[39,121,123],{"className":41,"code":122,"language":43,"meta":44,"style":44},"Builder::macro('whereLike', function($column, $search) {\n  return $this->where($column, 'LIKE', \"%{$search}%\");\n});\n",[46,124,125,130,135],{"__ignoreMap":44},[49,126,127],{"class":51,"line":52},[49,128,129],{},"Builder::macro('whereLike', function($column, $search) {\n",[49,131,132],{"class":51,"line":58},[49,133,134],{},"  return $this->where($column, 'LIKE', \"%{$search}%\");\n",[49,136,137],{"class":51,"line":64},[49,138,139],{},"});\n",[10,141,142],{},"The way we can use this macro now is simple:",[39,144,146],{"className":41,"code":145,"language":43,"meta":44,"style":44},"User::whereLike('username', $username)\n  ->whereLike('email', $email)\n  ->get();\n",[46,147,148,153,158],{"__ignoreMap":44},[49,149,150],{"class":51,"line":52},[49,151,152],{},"User::whereLike('username', $username)\n",[49,154,155],{"class":51,"line":58},[49,156,157],{},"  ->whereLike('email', $email)\n",[49,159,160],{"class":51,"line":64},[49,161,67],{},[10,163,164,165,168],{},"We can still improve the macro we just wrote. This macro only covers if we want to search only one column. So, if we want to search multiple columns then we have to extend this macro to support multiple columns. If we want to perform multiple column search we are going to use the ",[46,166,167],{},"orWhere"," Eloquent's method. Let's do that.",[39,170,172],{"className":41,"code":171,"language":43,"meta":44,"style":44},"Builder::macro('whereLike', function($columns, $search) {\n  $this->where(function($query) use ($columns, $search) {\n    foreach(array_wrap($columns) as $column) {\n      $query->orWhere($column, $search);\n    }\n  });\n\n  return $this;\n});\n",[46,173,174,179,184,189,195,201,207,214,220],{"__ignoreMap":44},[49,175,176],{"class":51,"line":52},[49,177,178],{},"Builder::macro('whereLike', function($columns, $search) {\n",[49,180,181],{"class":51,"line":58},[49,182,183],{},"  $this->where(function($query) use ($columns, $search) {\n",[49,185,186],{"class":51,"line":64},[49,187,188],{},"    foreach(array_wrap($columns) as $column) {\n",[49,190,192],{"class":51,"line":191},4,[49,193,194],{},"      $query->orWhere($column, $search);\n",[49,196,198],{"class":51,"line":197},5,[49,199,200],{},"    }\n",[49,202,204],{"class":51,"line":203},6,[49,205,206],{},"  });\n",[49,208,210],{"class":51,"line":209},7,[49,211,213],{"emptyLinePlaceholder":212},true,"\n",[49,215,217],{"class":51,"line":216},8,[49,218,219],{},"  return $this;\n",[49,221,223],{"class":51,"line":222},9,[49,224,139],{},[10,226,227,228,231,232,235,236,238],{},"So now, if we pass a single column (using the array_wrap function we convert it to an array), and search that column, but if we add multiple columns in an array than we loop through all of them and search the search term in all of those columns. Everything is wrapped in a ",[46,229,230],{},"where"," query because we don't want the ",[46,233,234],{},"whereLike"," query to mess up any other ",[46,237,230],{}," queries we can perform on the Eloquent model.",[10,240,241],{},"You can use this macro now like this:",[39,243,245],{"className":41,"code":244,"language":43,"meta":44,"style":44},"User::whereLike(['username', 'email'], $search)\n  ->where('enabled', true)\n  ->get();\n",[46,246,247,252,257],{"__ignoreMap":44},[49,248,249],{"class":51,"line":52},[49,250,251],{},"User::whereLike(['username', 'email'], $search)\n",[49,253,254],{"class":51,"line":58},[49,255,256],{},"  ->where('enabled', true)\n",[49,258,259],{"class":51,"line":64},[49,260,67],{},[72,262,264],{"id":263},"second-approach-using-scopes","Second approach: Using scopes",[10,266,267,268,273,274,277],{},"If you don't need the 'search' functionality in all of your models, you can define a ",[14,269,272],{"href":270,"rel":271},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F5.0\u002Feloquent#query-scopes",[18],"scope"," for your model. If we want to do this on the User model, open the ",[46,275,276],{},"User.php"," model and add the scope like this:",[39,279,281],{"className":41,"code":280,"language":43,"meta":44,"style":44},"public function scopeWhereLike($query, $columns, $search) {\n  $query->where(function($q) use ($columns, $search) {\n    foreach(array_wrap($columns) as $column) {\n      $q->orWhere($column, $search);\n    }\n  });\n\n  return $query;\n}\n",[46,282,283,288,293,297,302,306,310,314,319],{"__ignoreMap":44},[49,284,285],{"class":51,"line":52},[49,286,287],{},"public function scopeWhereLike($query, $columns, $search) {\n",[49,289,290],{"class":51,"line":58},[49,291,292],{},"  $query->where(function($q) use ($columns, $search) {\n",[49,294,295],{"class":51,"line":64},[49,296,188],{},[49,298,299],{"class":51,"line":191},[49,300,301],{},"      $q->orWhere($column, $search);\n",[49,303,304],{"class":51,"line":197},[49,305,200],{},[49,307,308],{"class":51,"line":203},[49,309,206],{},[49,311,312],{"class":51,"line":209},[49,313,213],{"emptyLinePlaceholder":212},[49,315,316],{"class":51,"line":216},[49,317,318],{},"  return $query;\n",[49,320,321],{"class":51,"line":222},[49,322,323],{},"}\n",[10,325,326,327,331,332,331,337,342],{},"There are many options if you need a more advanced search. Here are some of them like ",[14,328,19],{"href":329,"rel":330},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F5.7\u002Fscout",[18],", ",[14,333,336],{"href":334,"rel":335},"https:\u002F\u002Fwww.algolia.com\u002F",[18],"Algolia",[14,338,341],{"href":339,"rel":340},"https:\u002F\u002Fwww.elastic.co\u002F",[18],"Elasticsearch",".",[10,344,345],{},"Pick the approach that fits your project scope. If you need search on most models, go with macros. If it's isolated to one or two, scopes keep things tidy.",[347,348,349],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":44,"searchDepth":58,"depth":58,"links":351},[352,353],{"id":74,"depth":58,"text":75},{"id":263,"depth":58,"text":264},"Laravel","2019\u002F07\u002F16","You can always install Laravel Scout and use some of its engines for searching. However sometimes we don't need that heavy-on-server search, so we can use this simple approach for searching data in your databases.",null,"md","\u002Fimages\u002Flaravel-eloquent.jpeg","laravel eloquent, eloquent search, model search, eloquent models, eloquent scopes, larvel scopes, laravel macros, eloquent macros",{},"\u002Fblog\u002Fpragmatic-and-lightweight-search-for-laravel-models","☕️ 4 min read",{"title":5,"description":356},"pragmatic-and-lightweight-search-for-laravel-models","blog\u002Fpragmatic-and-lightweight-search-for-laravel-models","laravel, advanced laravel, laravel's eloquent","JJOyRjkNLlsYxmS76Lz1zTroOLsCA3IJOhXzerQ6xDU",1774945272418]