Search Value in Laravel Collection - php

I have a collection which contain user contacts, I want to search a value in this collection.
I tried $itemCollection->where('username', $search); but it`s showing me only if $search value is fully equal to username but I want to get results which has contains that value too.
For example I have "yunus" value as an username and when I`m searching "yunus" it is working well but I want to see result if I search "yun" or "y" values too.
I searched it and I did found I must to use where 'like' method but I did discovered it is not working for collections :(
My function for get user contacts which has my searched username value
public function index(Request $request)
{
$contacts = [];
$user = request()->user();
$search = $request->search;
Contact::for($user->id)
->orderBy('created_at', 'DESC')
->get()
->each(function ($contact) use ($user, &$contacts) {
$friend = $contact->user1_id === $user->id ? $contact->user2 : $contact->user1;
$contacts[] = $friend->toArray() + ['room' => $contact->room->toArray()];
});
$itemCollection = collect($contacts);
$filtered = $itemCollection->where('username', $search);
$filtered->all();
return response()->json($filtered);
}
Result : Json output

Try using filter() instead of where():
$itemCollection = collect($contacts);
$filtered = $itemCollection->filter(function($item) use ($search) {
return stripos($item['username'],$search) !== false;
});
https://laravel.com/docs/5.7/collections#method-filter

Related

Laravel execute where condition based on variable null or not

I am new to laravel. I want to execute my where condition if my variable value is not null. I tried the below code exactly not getting an idea of what to do.
$search = $array['search'];
$id = $array['id'];
$Data = Model::where('id', '=', $id)
if($search != '') {
//I want to include where condition here
}
Use Conditional Clauses
Model::when($search !== null, function ($query) use ($search) {
return $query->where('column', $search);
})
Your $Data variable is an Eloquent Query Builder object so you can add conditions to it for the query you are building:
if ($search) {
$Data->where('field', $search);
}

How to use query result and query again using LIKE statement in Laravel

I am trying to use questions result and get question again if title has some char in it.
If I query in condition_question table, I get results as expected.
public function showQuestions($category)
{
$myArray = array($category);
$questions = Question::whereIn('question_id', function ($query) use ($myArray) {
$query->select('question_id')
->from('condition_question')
->whereIn('condition_id', $myArray);
})->orderBy('question_id', 'desc')->paginate(20);
return QuestionLiteResource::collection($questions);
}
Question: How can I use now $questions result and query again with LIKE statement. So far I tried many thing, for example like this, but something is missing as I am getting errors:
public function showQuestions($category, $queryQuestion)
{
$myArray = array($category);
$chary = $queryQuestion;
$questions = Question::whereIn('question_id', function ($query) use ($myArray) {
$query->select('question_id')
->from('condition_question')
->whereIn('condition_id', $myArray);
})->get();
$results = $questions->where('question_title', 'LIKE', "%{$chary}%")->get();
return QuestionLiteResource::collection($results->values());
}
I know it is not my best, but need some help...It would be also cool to have paginated result at the end.
So, how to get collection of questions from questions table where title has char. Any help would be most welcomed!
You might know that once you call get() function, you got the results and not able to query any further. Maybe this is gonna work:
public function showQuestions($category, $queryQuestion)
{
$myArray = array($category);
$chary = $queryQuestion;
$questions = Question::whereIn('question_id', function ($query) use ($myArray) {
$query->select('question_id')
->from('condition_question')
->whereIn('condition_id', $myArray);
})
->where('question_title', 'LIKE', "%{$chary}%")
->get();
return QuestionLiteResource::collection($questions);
}
Since you have called get() on question query, you get the result as an Laravel Collection.
To filter through collection you can use filter() function.
Example Code
$results = $questions->filter(function($question) use ($chary) {
return Str::contains($question->question_title, $chary);
});
i think you can use join():
public function showQuestions($category, $queryQuestion)
{
$myArray = array($category);
$chary = $queryQuestion;
$query = Question::getModel()->newQuery();
$questions = $query
->join('condition_question', function (Builder $join) use ($myArray) {
$join->on('questions.question_id', '=', 'condition_question.question_id');
$join->whereIn('condition_question.condition_id', $myArray);
})
->where('questions.question_title', 'like', $chary)
->orderBy('questions.question_id', 'desc')
->paginate(20)
return QuestionLiteResource::collection($questions);
}

Using Full-Text-Search in order to find partial words by laravel query builder

I would like to write search query that uses supplied phrase to search a table, return the value that matches any part of the phrase.
this code is working, but results are nothing. For example, table have 'abcde', and I searched 'bcd', result is nothing.
protected function fullTextWildcards($term)
{
return str_replace(' ', '*', $term) . '*';
}
public function index(Request $request, $slug = null)
{
$query = $slug
? \App\Tag::whereSlug($slug)->firstOrFail()->articles()
: new \App\Article;
if ($keyword = request()->input('q')) {
$raw = 'MATCH(title,content) AGAINST(? IN BOOLEAN MODE)';
$query = $query->whereRaw($raw, [$this->fullTextWildcards($keyword)]);
}
$articles=$query->latest()->paginate(10);
return view('articles.index',compact('articles'));
}
How to chain everything together so I achieve the desired result?
Thanks in advance.
You can just use like in your query to get any matches in a given column. Try this:
public function index(Request $request, $slug = null)
{
$filter = ['keyword' => $request->q , 'slug' => $slug];
$articles = \App\Tag::where(function ($q) use ($filter){
//you can leave this I just put the so the code seems clean
if ($filter['slug'] !== null) {
$q->whereSlug($slug);
}
if ($filter['keyword']) {
$keyword = $this->fullTextWildcards($filter['keyword']);
//you can use **like** this
$q->where('title', 'like', "%".$keyword."%")->orWhere('content', 'like', "%".$keyword."%");
}
})->latest()->paginate(10);
return view('articles.index',compact('articles'));
}
Hope this helps

Laravel query whereIn - show results from which search

I have an array that comes to controller's action.
$arrOfTags = $request['position'];
That array looks like :
['manager', 'consultant'];
Next, I am querying the DB for CV's where position is one of these.
$query = Cv::query();
$query->whereIn('position', $arrOfTags);
...
->get();
Now the question :
If $request['position'] = ['manager','consultant']; and whereIn clause finds result just for position = 'consultant' and none for 'manager', how can I programmatically discover that results are found for 'consultant' and/or didn't found for 'manager' ?
EDIT
All my query's code :
$arrOfTags = explode(',', $request['position']);
$query = Cv::query();
$query->whereIn('position', $arrOfTags)
if($request['salary']) {
$query->whereIn('salary', $request['salary']);
}
if($request['skill']) {
$query->join('skills', 'cvs.id', '=', 'skills.cv_id')
->join('allskills', 'skills.allskills_id', '=', 'allskills.id')
->select('cvs.*', 'allskills.name AS skillName')
->whereIn('skills.allskills_id', $request['skill']);
}
if($request['language']) {
$query->join('languages', 'cvs.id', '=', 'languages.cv_id')
->join('alllanguages', 'languages.alllanguages_id', '=', 'alllanguages.id')
->select('cvs.*', 'alllanguages.name as languageName')
->whereIn('languages.alllanguages_id', $request['language']);
}
$cvs = $query->distinct()->get();
Imagine that $arrOfTags values are ['manager', 'consultant', 'sales']
I want somehow to discover that results was found for position =
manager and consultant, and didn't found for position = 'sales'
You can load the data from DB:
$cvs = CV::....;
And then use the partition() method:
list($manager, $consultant) = $cvs->partition(function ($i) {
return $i['position'] === 'manager';
});
Or the where() method:
$manager = $cvs->where('position', 'manager');
$consultant = $cvs->where('position', 'consultant');
Both partition() and where() will not execute any additional queries to DB.
You can do this way too:
$managers = $collection->search(function ($item, $key) {
return $item['position'] === "manager";
});
$consultants = $collection->search(function ($item, $key) {
return $$item['position'] === "consultant";
});
You could use count().
if(($query->count)==($query->where('position','consultant')->count())){
///all are coming for position=consultants
}
Or you could use groupBY-
$query = $query->groupBy('position')->toArray();
And retrieve by-
$consultants = $query['consultant'];

Laravel 5 Database Like query on a array

I have been working on a laravel advance search filter where a user can input several field in a form and on submit it generates data table for given fields. and if fields are empty then it just shows all the records from database (unsets the filter).
public function advanced_search(Request $request)
{
//user submitted data in post
$post = $request->all();
/*
filter array keys are defined here
e.g first_name, last_name
*/
$simple_filter = array(
"first_name" => "",
"last_name" => "",
"email" => "",
"company_name" => "",
);
foreach ($simple_filter as $key => $value) {
if (isset($post[$key]) && ($post[$key] != null) && !empty($post[$key])) {
$simple_filter[$key] = $post[$key];
} else {
//user didn't send this field in post data so removing this from filter list
unset($simple_filter[$key]);
}
}
$query = DB::table('contacts')->where($simple_filter)->get();
return DataTables::of($query)
->toJson();
}
Now this code is working fine. But requirements are changed. This code only return the exact details. Now I want to show record even if substring matches. (LIKE %data$). How can I modify this?
Use orWhere() if you want to find contacts where one of the fields is like a given form input. Or use where() if you want to use all the form input elements to filter contacts:
public function advanced_search(Request $request)
{
$query = Contact::query();
$fields = ['first_name', 'last_name', 'email', 'company_name'];
foreach ($fields as $field) {
if ($request->filled($field)) {
$query = $query->orWhere($field, 'like', '%' . $request->get($field) . '%');
}
}
return DataTables::of($query->get())->toJson();
}
Also, you're doing a lot of redundant checks. Just use the ->filled() method instead. It will return false if a field is empty, or doesn't exist or null.
If you would like to determine if a value is present on the request and is not empty, you may use the filled method
https://laravel.com/docs/5.5/requests#retrieving-input
You can create the query before the loop and add all where filters in the loop. The second parameter of the where function can be the comparer, in your case: like.
$query = DB::table('contacts');
foreach ($simple_filter as $key => $value) {
if (isset($post[$key]) && ($post[$key] != null) && !empty($post[$key]))
{
$query = $query->orWhere($key, 'like', '%' . $value . '%');
}
}
return DataTables::of($query->get())->toJson();

Categories