How to do a where() on any column in model - laravel

I have four columns that I want to do a LIKE query on, user_id,client_id, and start_time, and end_time
I have the current statement
Model::where('client_id','LIKE','%'.$q.'%')
However, instead of it being client_id, I'd like to be able to search through all four of those columns rather then just one, without using a whereOr as that does not work efficiently for my problem
Thank you in advance.

You may do like this below.
Model::where(function($q) {
$q->where('user_id','LIKE','%'.$q.'%')
->orWhere('client_id','LIKE','%'.$q.'%')
->orWhere('start_time','LIKE','%'.$q.'%')
->orWhere('end_time','LIKE','%'.$q.'%');
});
Hope that helps.

You can use when and filter if you have setted one or another variable:
Model::when(isset($client_id),function($query) use ($client_id) {
$query->where('client_id','=', $client_id)
})
->when(isset($user_id),function($query) use ($user_id) {
$query->where('user_id','=', $user_id)
})
->when(isset($start_time),function($query) use ($start_time) {
$query->where('start_time','=',$start_time)
})
->get();

You can use where and Search records
$user_id = $request->user_id ? '%' . $request->user_id . '%' : '';
$client_id = $request->client_id ? '%' . $request->client_id . '%' : '';
$modal = Modal::where(function($q) use($user_id, $client_id) {
$q->where("user_id", "like", "$user_id")
->orwhere("client_id", "like", "$client_id");})->get();
dump($modal->count()); // count display
Hope that helps.

Related

How to find Array values to search in FIND_IN_SET

Hi I am facing a problem with Laravel eloquent query. I have a table named as 'Offer' and it is connected to another table using relation function 'ApplyOn'. here is the code
$offer = Offer::whereHas('ApplyOn',function($query) use ($input){
$query->whereRaw("find_in_set(".$input['size_id'].",size_ids)");
})->get();
here $input['size_id'] is an array so I can't get the result using this query please help me to find out the solution.
if it is not possible with the find_in_set function then how can I solve this problem? I want to sort the data by the given array value.
The $input['size_id'] is an array. for example [1,2,3].
The table field 'size_ids' is a string value with comma-separated. for example 1,2,3,4,5
Offer table
ApplyOn table
You want find all the size Ids matching with the $input['size_id'] and this is an array you can do something like
$offer = Offer::whereHas('ApplyOn', function ($query) use ($input) {
if (isset($input['size_id']) and is_array($input['size_id'])) {
$ids_to_filter = $input['size_id'];
$query->where(function ($sub) use ($ids_to_filter) {
foreach ($ids_to_filter as $value) {
$sub->where('size_ids', 'like', '%' . $value . '%');
}
});
}
})->get();
If with only ONE is a valid ApplOn use an WHERE OR
$sub->orWhere('size_ids', 'like', '%' . $value . '%');
Maybe this can help you
If you just want to filter the data with an array, you can use whereIn.
example -
$offer = Offer::whereHas('ApplyOn', function ($query) use ($input) {
$query->whereIn("field_name", $input['size_id']);
})->get();
If you have saved the data as a string, and need to filter you can use like.
$offer = Offer::whereHas('ApplyOn', function ($query) use ($input) {
$query->where("field_name", 'LIKE', '%' . $input['size_id'] . '%');
})->get();

How to return paging cache in laravel?

I would like to know if there is any way to page this query that I do in Laravel and store it in the cache.
I've already put ->paginate() but it seems that the cache doesn't return in Eloquent but as an object. I checked the variable's type with gettype().
this is my role. Can anyone help me?
public function getProductsRecommendations($keywords)
{
$expiration = 10;
$keyName = 'productsRecommended';
$list = Cache::remember($keyName, $expiration, function () use ($keywords) {
return Product::query()->where(function ($productsAll) use ($keywords) {
if ($keywords) {
foreach ($keywords as $keyword)
$productsAll->orWhere('title', 'LIKE', '%' . $keyword . '%')->orWhere('description', 'LIKE', '%' . $keyword . '%')->orWhere('code', 'LIKE', '%' . $keyword . '%');
}
})->where('status', 'active')->get();
});
return $list;
}
You should cache your results per page, with a key that is the current page. Something like:
$currentPage = request()->get('page',1);
$category = Cache::remember('sellcategory-' . $currentPage, 10, function(){
return DB::table('elans')->orderBy('updated_at', 'desc')->where(['derc' => 1,'elaninnovu' => 'Satılır'])->paginate(10);
});
I managed to do what I needed. I'll leave it here in case someone goes through the same problem and finds this question.
Sometimes you might want to create an instance of paging manually, passing in an array of items. You can do this by creating an Illuminate\Pagination\Paginator or Illuminate\Pagination\LengthAwarePaginator instance, depending on your needs.
To exemplify:
use Illuminate\Pagination\Paginator;
$paginator = new Paginator($array, $rowPerPage, $currentPage = null);

how can i search multiple keywords in laravel .?

This is my controller
$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'));
This is working good for single keyword search. But I want to use it for multiple keywords. Like laravel php etc. Please guide me when I search multiple values like abc php laravel or anything then it should work. If tags exists in different column like php is present in 1st column and laravel is in next column when I search php laravel then it should show me both column values.
There is probably a better way to do this, like using CloudSearch/Algolia, but this is a solution that has worked for us:
// 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();
I spent lots of time on this over the past couple days, and here is my solution. It's similar to these other ones but different, so it may be of value for someone one day:
I have a Vue component that makes a GET request, so $request->get('searchTerms') comes from <input name="searchTerms"> in the HTML form submit.
I wanted to allow to user to control which fields were going to be searched, so that's why $search_terms is an array of columns to search.
I wanted it so if the user searched for "McDonalds 604" that it would filter the list of records and show two different matches for that search. One matching "McDonalds" for business_name and one matching "604" for the area code of the phone_number. This would ensure the user would get everything related in case they only knew some fragments.
The goal was to iterate over the search terms and also to iterate over the search fields (columns) with a generic formula that could be applied from any number of search terms and columns, dynamic at runtime.
$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();
I would recommend reading through the query docs for Laravel because it will give you better intuition about this task: https://laravel.com/docs/5.6/queries
In the above code, we are using parameter grouping and it changes the characteristics of the algorithm if you use where vs. orWhere.
Bonus Factoids
I also highly recommend testing your SQL statements using $query->toSql() and $query->getBindings(). You can put those in place of $query->get() to see what the SQL statement it is generating will look like and what the parameter bindings are. getBindings() will show you what the values of the ? are in toSql().
You need to prepare the $terms array first, then just iterate over it and add orWhere() clauses.
I've just tested it and for whereHas() closure you need to use where() for the first term and orWhere()for the rest of it to make it work:
$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();
If you'll decide to use = instead of like, just use whereIn() instead of building query with a bunch of orWhere().

Condition in a search query doesn't work

I have a search query fonction who seems to not work with the last condition . (->where('structure_id' , '=' , $mastructure);
I fact when i run the query i get also the other licences from other "structure_id "
here my search controller
public function getLicenciesStructure(Request $request){
$mastructure = Auth::user()->structure->id ;
$search = $request->get('recherche');
if ($search) {
$query = Licencies::Where('lb_nom', 'like', "%$search%")->orWhere('num_licence' , 'like' , "%$search%")->where('structure_id' , '=' , $mastructure);
}
$licenciestructures = $query->paginate(10)
->appends(['recherche' => $search]);
return view('licencie_structure/index' , compact('licenciestructures' , 'mastructure'));
}
Someone have an idea why the query display also the other items from other structure_id ? thanks a lot in advance
Use where() closure:
Licencies::where(function($q) use($search) {
$q->where('lb_nom', 'like', '%'.$search'%')
->orWhere('num_licence', 'like', '%'.$search.'%');
})->where('structure_id', $mastructure);

Check lowercase and uppercase search

I'm using this query:
public function autocomplete(Request $request)
{
$company_name = $request->input('query');
$data = BusinessUser::where("company_name","LIKE",'%'. $company_name .'%')->pluck('company_name');
return response()->json($data);
}
In database for company name i can have this: 'Test','TEST','test'.
So how can i check all of this so that i get result. Any suggestion?
I tried this but then i get an error that i need to pass array:
$data = BusinessUser::whereRaw("company_name","LIKE",'%'. $company_name .'%')->orWhereRaw("company_name","LIKE",'%'. $company_name .'%')->pluck('company_name');
EDIT:
I dont want to change anything in database
You can use LOWER:
BusinessUser::whereRaw('LOWER(`company_name`) like ?', ['%'.strtolower($company_name).'%'])->pluck('company_name');
Here is an answer without using whereRaw:
use DB;
$data = BusinessUser::where(DB::raw('LOWER(company_name)'), 'like', '%' . strtolower($company_name) . '%');
Set an encoding for company_name to utf8_general_ci. CI means Case-Insensitive.
Your query should look like this:
$data = BusinessUser::whereRaw("company_name COLLATE UTF8_GENERAL_CI LIKE %{$company_name}%")->pluck('company_name');

Resources