Use where like for relative search in laravel - laravel

I am doing data search function in php . I use mongoDB. I have a table user:
id name status
1 tèo 1
2 tý 2
In UserRepository.php :
<?php
namespace App\Repositories\Backend\MongoDB;
use App\Models\User;
use App\Repositories\MongoDBBaseRepository;
class UserRepository extends MongoDBBaseRepository
{
public function model()
{
return MoviePassContent::class;
}
public function search($keyword)
{
$search = $this->model->where('name', 'like', '%'.$keyword.'%')->get()->toArray();
// I tried more of these ways, but it still doesn't work
// $search = $this->model->where('name', 'like', $keyword.'%')->get()->toArray();
// $search = $this->model->where('name', 'like', '%'.$keyword)->get()->toArray();
}
}
If the $keyword I enter is : tèo, the result is correct. But when I enter $keyword as teo or t it returns null. Where did I go wrong. Please give me your opinion. Thank you.

It's not related to Laravel or PHP. It all depends on your database. Try to utilize a different collation charset on your database.
Example below changes your collation and charset to utf32. Careful, make sure to backup your database to prevent any data loss! This action may cause partial or full data loss:
ALTER DATABASE your_db_name
CHARACTER SET utf32]
COLLATE utf32_general_ci
You may tweak it to find the best fit for you, it depends on what kind of data you're inserting into the db.
Another safer alternative is to mitigate it on application layer. Define a scope which will help with special character conversions.
As for the: "searching by 't' but not appearing" issue, it seems like DBMS config problem. Even though it usually applies for FULLTEXT search, there might be some setting about min-length regarding LIKE queries.

Assuming you are using jenssegers/laravel-mongodb then you can achieve this with ->options to your query:
$search = $this->model
->where('name', 'like', '%'.$keyword.'%')
->options([
'collation' => [
'locale' => 'en',
'strength' => 1
]
])->get()->toArray();
Check https://www.mongodb.com/docs/v5.3/reference/collation/ for more details on the collation option

Related

Livewire filter with multiple conditions : How to?

I am in trouble with a little functionnality I want to add in my project, sure someone can help me :)
The stack is Laravel with Livewire to add easily some interactivity.
I have a table with a list of bills. I use Livewire pagination in this table, and I have a search field to dynamically filter those bills.
There's no problem for a simple filter, for example by bill numerotation, or by date, or both... using where and orWhere clauses.
I have an additionnal filter, activated by a button, which filters bills by "paid or not".
For this case, my Livewire Controller should look like this :
public function render()
{
return view('livewire.bills.index', [
'bills' => Bill::where('numero', 'like', '%'.$this->search.'%') // string modified by search input
->orWhere('created_at', 'like', '%'.$this->search.'%') // string modified by search input
->where('paid', $this->paid) // bool switched by click on a button
->paginate(12),
]);
}
In addition, I want to allow filter by customer name. Of course, Bill Model and Customer Model are relationned in a One-To-many Relationship :
-- Bill --
-id
-numero (string)
-customer_id (foreign)
-paid (bool)
-price(int)
-created_at (datetime)
-- Customer --
-id
-name (string)
To allow filter by customer name and 'paid or not', i use whereHas clause in addition to the where clause :
'bills' => Bill::whereHas('customer', function($query) {
return $query->where('name', 'like', '%'.$this->search.'%');
})
->where('paid', $this->paid)
->paginate(12),
Everything's ok. But I can't add the third filter (filter by created_at) in addition of those 2 filters.
I tried this :
return view('livewire.devis.index', [
'bills' => Bill::whereHas('customer', function($query) {
return $query->where('name', 'like', '%' . $this->search . '%');
})
->orWhere('created_at', 'like', '%' . $this->search . '%')
->where('paid', $this->paid)
->paginate(12),
]);
It works for filtering by customer name or by date (search field), but the 'paid or not' filter doesn't work anymore.
Anyone can help me to understant where my query is failing please.
Thanks to everybody who's watching this and maybe could give me a hand

Laravel: How to ignore database field's special characters when doing a 'LIKE' query?

I want to ask for your help as I'm having challenges creating a Laravel query.
Here's my current code:
$products = Product::where(function($query) use ($searchTerm) {
$query->where('product_name', 'LIKE', "%$searchTerm%");
$query->orWhere('product_category', 'LIKE', "%$searchTerm%");
$query->orWhere('product_description', 'LIKE', "%$searchTerm%");
})
->where('lang', '=', 'en')
->orderBy('product_name', 'ASC')
->get();
If I have a product named Michael's Handsoap and the user searches using the keyword "Michaels", it returns nothing with the above query. Is there a way to remove special characters from database fields as you do the query? Any input would be appreciated.
Thanks!
EDIT: Figured that it's best just to add a product_name_search column that contains the product name stripped of special characters (using, for example, preg_replace("/[^A-Za-z0-9 ]/", '', $productName))
This way, $query->where('product_name_search', 'LIKE', "%$searchTerm%") can now be used. It adds another parameter, but at least you've covered them all now.

How to fetch certain keyword's record in Laravel?

I would like to LIKE search.
If 'product' column has "AQ" string display data.
I wrote below code but I couldn't get any record.
Could you teach me right code please?
public function w_mo_fb_m()
{
$word = "AQ";
$images = ImageGallery::where('product', 'like', "%$word%")->orderBy('id', 'desc')->get();
return view('w_mo_fb_m',compact('images'));
}
How about try this.
where('product', 'LIKE', '%'.$word.'%')
//or
where('product', 'LIKE', "%{$word}%")
If this still not working you may need to run raw SQL to see if you can get any record. (you need to replace ImageGallery with your actual table name)
DB::select('select * from ImageGallery where product LIKE = ?', ['%'.$word.'%']);

How to use Model's getter Attribute to use in Query Builder

Described below is my getter in my Post model:
public function getTicketIdAttribute() {
return str_pad($this->id, 6, '0', STR_PAD_LEFT);
}
Note that the function simply adds 6 zero padding at the front of the Post's post_id.
Now, is it possible to use it in a query builder? Ihave tried the following:
Post::where(function($query) use ($keyword) {
$query->where('detail', 'LIKE', '%'. $keyword .'%')
->orWhereHas($query->getTicketIdAttribute(), 'LIKE', '%'. $keyword .'%');
});
What I'm trying to do is to have a search engine which look for Post object if:
$keyword matches the Post's detail
or
if $keyword matches the getTicketIdAttribute()
As pointed out by Jonas Staudenmeir I need to rewrite the code using PHP's LPAD(), so:
LPAD(id, 6, '0')
and to use it in Query Builder I need to apply it using the DB::raw method as there is no equivalent LPAD() method available right out the box. So, use it like this:
DB::raw("LPAD(id, 6, '0')")
Just a note that this means for this case the Model's getter Attribute cannot be used directly in Query Builder, so need to apply it this way.
Hope this help others, and I thank Jonas Staudenmeir for the help.

Acces to a model relation in an Eloquent Query

I try to make a particular query but i'm not sure how to achieve this , i would like to access to saison table
{{ \App\Licencies::where(['structure_id' => Auth::user()->structure->id])->where(['saison_id->dt_fin' , '<' , \Carbon\Carbon::now()])->count() }}
here the saison() relation in my model , that i can access very well
$licencie->saison->dt_fin < \Carbon\Carbon::now()
someone knows to right query ? thanks a lot in advance
Thanks for the explanation in the comment.
In the Laraval documentation there is the following example:
// Retrieve all posts with at least one comment containing words like foo%
$posts = Post::whereHas('comments', function ($query) {
$query->where('content', 'like', 'foo%');
})->get();
Which can easily be transformed for your purpose:
// Retrieve all licencies where the saison has a dt_fin before now
$licencies = \App\Licencies::whereHas('saison', function ($query) {
$query->where('dt_fin', '<', \Carbon\Carbon::now());
})->get();
If it still returns errors, let us know! (kinda hard to test without carbin and a structure that is equal to yours)

Resources